Due to @Erel's comment below, I've rewritten this in pure B4X basic. The new version should work with B4A, B4J and B4i. New version (that should be used) can be found here https://www.b4x.com/android/forum/t...byte-array-with-resize-quality-options.91774/.
Example
Resources used:
Image resizing
https://stackoverflow.com/a/4205711
https://stackoverflow.com/questions/21540378/convert-javafx-image-to-bufferedimage
https://stackoverflow.com/a/13605411
https://www.mkyong.com/java/how-to-convert-bufferedimage-to-byte-in-java/
JPEG quality
https://www.b4x.com/android/forum/threads/solved-how-to-create-jpeg-output-stream.83830/#post-531280
http://www.java2s.com/Code/Java/2D-Graphics-GUI/WritesanimagetoanoutputstreamasaJPEGfileTheJPEGqualitycanbespecifiedinpercent.htm
B4X:
' Converts image to JPEG a byte array of the resulting JPEG. 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 Java's default quality
Sub ImageToJPEGByteArray(aImage As Image, width As Int, height As Int, quality As Int) As Byte()
Dim jo As JavaObject = Me
Return jo.RunMethod("imageToJPEGByteArray", Array As Object (aImage, width, height, quality))
End Sub
B4X:
#if Java
import java.awt.image.BufferedImage;
import java.awt.geom.AffineTransform;
import java.awt.Graphics2D;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Iterator;
import java.util.Locale;
import javafx.scene.image.Image;
import javafx.embed.swing.SwingFXUtils;
import javax.imageio.IIOImage;
import javax.imageio.ImageIO;
import javax.imageio.ImageWriteParam;
import javax.imageio.ImageWriter;
import javax.imageio.plugins.jpeg.JPEGImageWriteParam;
import javax.imageio.stream.ImageOutputStream;
// Image resizing
// https://stackoverflow.com/a/4205711
// https://stackoverflow.com/questions/21540378/convert-javafx-image-to-bufferedimage
// https://stackoverflow.com/a/13605411
// https://www.mkyong.com/java/how-to-convert-bufferedimage-to-byte-in-java/
// JPEG quality
// https://www.b4x.com/android/forum/threads/solved-how-to-create-jpeg-output-stream.83830/#post-531280
// http://www.java2s.com/Code/Java/2D-Graphics-GUI/WritesanimagetoanoutputstreamasaJPEGfileTheJPEGqualitycanbespecifiedinpercent.htm
// Converts image to JPEG a byte array of the resulting JPEG. 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 Java's default quality
public static byte[] imageToJPEGByteArray(Image aImage, int width, int height, int qualityPercent) throws IOException {
byte[] imageBytes = new byte[0];
if ((qualityPercent < -1) || (qualityPercent > 100)) {
throw new IllegalArgumentException("Quality out of bounds!");
}
float quality = qualityPercent / 100f;
double oldWidth = aImage.getWidth();
double oldHeight = aImage.getHeight();
if (oldWidth == 0 || oldHeight == 0) {
throw new IllegalArgumentException("Source image with 0 width and/or height!");
}
boolean resize = true;
if ((width == 0 && height == 0) || (width == -100 && height == -100)) resize = false;
BufferedImage destImage;
if (resize) {
double newWidth = (double) width;
double newHeight = (double) height;
// Calculate new dimensions
if (newWidth < 0) newWidth = -1 * oldWidth * newWidth / 100;
if (newHeight < 0) newHeight = -1 * oldHeight * newHeight / 100;
if (newWidth == 0) newWidth = oldWidth * newHeight / oldHeight;
if (newHeight == 0) newHeight = oldHeight * newWidth / oldWidth;
// Convert JavaFX image to BufferedImage and transform according to new dimensions
destImage = new BufferedImage((int) newWidth, (int) newHeight, BufferedImage.TYPE_INT_RGB);
BufferedImage srcImage = SwingFXUtils.fromFXImage(aImage, null);
Graphics2D g = destImage.createGraphics();
AffineTransform at = AffineTransform.getScaleInstance(newWidth/oldWidth, newHeight/oldHeight);
g.drawRenderedImage(srcImage, at);
g.dispose();
} else {
destImage = SwingFXUtils.fromFXImage(aImage, null);
}
// Output JPEG byte array
ByteArrayOutputStream baos = new ByteArrayOutputStream();
if(qualityPercent != -1) {
// Start to create JPEG with quality option
ImageWriter writer = null;
Iterator iter = ImageIO.getImageWritersByFormatName("jpg");
if (iter.hasNext()) {
writer = (ImageWriter) iter.next();
}
ImageOutputStream ios = ImageIO.createImageOutputStream(baos);
writer.setOutput(ios);
ImageWriteParam iwparam = new JPEGImageWriteParam(Locale.getDefault());
iwparam.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
iwparam.setCompressionQuality(quality);
writer.write(null, new IIOImage(destImage, null, null), iwparam);
ios.flush();
writer.dispose();
ios.close();
// Done creating JPEG with quality option
} else {
// This one line below created a JPEG file without quality option
ImageIO.write(destImage, "jpg", baos);
}
baos.flush();
imageBytes = baos.toByteArray();
baos.close();
// Done
return imageBytes;
}
#End If
Example
B4X:
Dim bImage As Image
bImage.Initialize(File.DirAssets, "b.png")
Dim c() As Byte = ImageToJPEGByteArray(bImage, -50, 0, 50)
'https://www.b4x.com/android/forum/threads/b4x-bytes-to-file.70111/#content
BytesToFile(File.DirApp, "b.jpg", c)
Resources used:
Image resizing
https://stackoverflow.com/a/4205711
https://stackoverflow.com/questions/21540378/convert-javafx-image-to-bufferedimage
https://stackoverflow.com/a/13605411
https://www.mkyong.com/java/how-to-convert-bufferedimage-to-byte-in-java/
JPEG quality
https://www.b4x.com/android/forum/threads/solved-how-to-create-jpeg-output-stream.83830/#post-531280
http://www.java2s.com/Code/Java/2D-Graphics-GUI/WritesanimagetoanoutputstreamasaJPEGfileTheJPEGqualitycanbespecifiedinpercent.htm
Last edited: