Originally posted a B4J/inline Java version of this in the B4J Code Snippets [//www.b4x.com/android/forum/t...byte-array-with-resize-quality-options.91746/]. @Erel pointed out though that the XUI library had the functionality that I was doing with Java, so I decided to rewrite the routine. This routine uses 100% B4X basic syntax, no inline Java, not even any
If conditionals. Unlike the Java version, this version does not throw any exceptions [on purpose], but instead returns an empty byte array if it finds/encounters any issues [which are Log[]'ed].
' Converts image to JPEG byte array. Ability to resize and adjust JPEG quality.
' Negative width and height values = %, such that -50 = 50% and -200 = 200%
' Positive width and height values = pixel dimensions
' If one value [either width or height] are 0, then the other value is proportionally
' calculated from the first.
' If both width and height are 0 or -100, no resizing takes place
' If quality = -1, use default quality of 75
' Will return a zero length byte array if something is wrong with the parameters
Sub XUIImageToJPEGByteArray[aImage As Object, width As Int, height As Int, quality As Int] As Byte[]
'Sanity check quality
If [quality < -1 And quality > 100] Then
Log["Parameter quality not in range [-1..100]"]
Return Array As Byte []
End If
If quality = -1 Then quality = 75
'Sanity check incoming image
Try
Dim image As B4XBitmap = aImage
Catch
Log[LastException]
Return Array As Byte []
End Try
'Sanity check incoming image dimensions
Dim oldWidth As Int = image.Width
Dim oldHeight As Int = image.Height
If [oldWidth = 0 And oldHeight = 0 ] Then
Log["Source image with incorrect dimensions"]
Return Array As Byte []
End If
'See if were resizing the image
Dim resize As Boolean = True
If [[width = 0 And height = 0] Or [width = -100 Or height = -100]] Then resize = False
'Resize if necessary
If [resize] Then
Dim newWidth As Int = width
Dim newHeight As Int = height
'Calculate new dimensions
If [newWidth < 0] Then newWidth = -1 * oldWidth * newWidth / 100
If [newHeight < 0] Then newHeight = -1 * oldHeight * newHeight / 100
If [newWidth = 0] Then newWidth = oldWidth * newHeight / oldHeight
If [newHeight = 0 ] Then newHeight = oldHeight * newWidth / oldWidth
image = image.Resize[newWidth, newHeight, False]
End If
'Convert image to JPEG byte array
Dim out As OutputStream
out.InitializeToBytesArray[0]
image.WriteToStream[out, quality, "JPEG"]
out.Close
'Done
Return out.ToBytesArray
End Sub
Example
Dim bImage As Image
bImage.Initialize[File.DirAssets, "b.png"]
Dim c[] As Byte = XUIImageToJPEGByteArray[bImage, -50, 0, 50]
'//www.b4x.com/android/forum/threads/b4x-bytes-to-file.70111/
# content
BytesToFile[File.DirApp, "b.jpg", c]
Resource used: Dim bImage As Image bImage.Initialize[File.DirAssets, "b.png"] Dim c[] As Byte = ImageToJPEGByteArray[bImage, -50, 0, 50] '//www.b4x.com/android/forum/threads/b4x-bytes-to-file.70111/
content BytesToFile[File.DirApp, "b.jpg", c]
Last edited: Apr 11, 2018
-
2
I try it out and if i compile it with B4J then i run into an Error:
B4J Version: 6.01
Parsing code. [0.00s]
Compiling code. [0.16s]
ObfuscatorMap.txt file created in Objects folder.
Compiling layouts code. [0.00s]
Organizing libraries. [0.00s]
Compiling generated Java code. Error
B4J line: 51
Dim image As B4XBitmap = aImage
javac 1.8.0_151
src\b4j\example\main.java:137: error: package android.graphics does not exist
_image.setObject[[android.graphics.Bitmap][_aimage]];
^
1 error
Attached is the project, maybe i missed something.
- Image to JPEG.zip 2.8 KB · Views: 536
-
3
_image.setObject[[android.graphics.Bitmap][_aimage]];
I've just opened your project and it complained about the missing xui library. That should not happen in B4J 6.01, since it has a version of the XUI library included, it's called jXUI. Looks like your using the Android version of the XUI library instead of B4J's internal XUI library [jXUI].
BTW: Thanks for including a test project. That gave me the clue as to what is going on.
Last edited: May 2, 2018
-
4
ahh ok, did not know that this is already present at B4J. Thanks.
-
5
May I know which Library is to be used for the type Image in the code "Dim bImage As Image"
Dim bImage As Image
bImage.Initialize[File.DirAssets, "b.png"]
Dim c[] As Byte = XUIImageToJPEGByteArray[bImage, -50, 0, 50]
'//www.b4x.com/android/forum/threads/b4x-bytes-to-file.70111/
# content
BytesToFile[File.DirApp, "b.jpg", c]
-
6
This code only works in B4J. I guess the code is NOT useable as B4X [B4A, B4J and B4i]. The Docs of this Object are pointing out that it is part of the jfx Library which is a B4j Library.
-
7
Replace:
Dim bImage As Image
bImage.Initialize[File.DirAssets, "b.png"]
Dim c[] As Byte = XUIImageToJPEGByteArray[bImage, -50, 0, 50]
'//www.b4x.com/android/forum/threads/b4x-bytes-to-file.70111/
# content
BytesToFile[File.DirApp, "b.jpg", c]
By:
Dim bImage As B4XBitmap
bImage = xui.LoadBitmap[File.DirAssets, "b.png"]
Dim c[] As Byte = XUIImageToJPEGByteArray[bImage, -50, 0, 50]
'//www.b4x.com/android/forum/threads/b4x-bytes-to-file.70111/
# content
BytesToFile[xui.DefaultFoler, "b.jpg", c]
And it becomes XUI.
-
8
Dim bImage As B4XBitmap
bImage = xui.LoadBitmap[File.DirAssets, "b.png"]
Dim c[] As Byte = XUIImageToJPEGByteArray[bImage, -50, 0, 50]
BytesToFile[File.DirDefaultExternal, "b.jpg", c]
The file created using BytesToFile[File.DirDefaultExternal, "b.jpg", c] is corrupted. Any idea why is it so. ?
I pick a file from Gallery, then resize and write it to File.DirDefaultExternal, unfortunately the file written is corrupted Here is the code that I use
Sub Process_Globals
'These global variables will be declared once when the application starts.
'These variables can be accessed from all modules.
Private cc As ContentChooser
End Sub
Sub Activity_Create[FirstTime As Boolean]
'Do not forget to load the layout file created with the visual designer. For example:
Activity.LoadLayout["Profile"]
If FirstTime Then
cc.Initialize["cc"]
End If
End Sub
Sub LblFromGallery_Click
cc.Show["image/*", "Choose image"]
End Sub
Sub cc_Result [Success As Boolean, Dir As String, FileName As String]
Dim realPath As String = GetPathFromContentResult[FileName]
Dim xIV As B4XView = ivProfilePic 'ivProfilePic is an ImageView
Dim bImage As B4XBitmap
Dim myXui As XUI
bImage = myXui.LoadBitmap[Dir, FileName]
Dim c[] As Byte = XUIImageToJPEGByteArray[bImage, -50, 0, 50]
'When I physicall check this file on File.DirDefaultExternal, it is corrupted
BytesToFile[File.DirDefaultExternal, "MyProfilePic.jpg", c]
xIV.SetBitmap[ LoadBitmapResize[File.DirDefaultExternal, "MyProfilePic.jpg", 332dip, 232dip, True ]]
End Sub
Sub BytesToFile [Dir As String, FileName As String, Data[] As Byte]
Dim out As OutputStream = File.OpenOutput[Dir, FileName, False]
out.WriteBytes[Data, 0, Data.Length]
out.Close
End Sub
Sub FileToBytes [Dir As String, FileName As String] As Byte[]
Return Bit.InputStreamToBytes[File.OpenInput[Dir, FileName]]
End Sub
Later I use the FileToBytes to read the image file and then write the image to a BLOB column in MySQL
Dim c[] As Byte = FileToBytes[File.DirDefaultExternal, "MyProfilePic.jpg"]
Last edited: Sep 8, 2018
-
9
If you upload your project, or at least enough of your project that replicates this issue, I’ll take a look at it
-
10
Your Code is working fine. It was my mistake. Sorry for the confusion.
-
11
I use this in a Non-Ui Project, on my local machine, it works good, but on my server [ubuntu] i have this error: