#if Java
import java.awt.AlphaComposite;
import java.awt.image.BufferedImage;
import java.awt.image.DataBufferByte;
import java.awt.geom.AffineTransform;
import java.awt.Graphics2D;
import javafx.scene.image.Image;
import javafx.embed.swing.SwingFXUtils;
import org.opencv.core.CvType;
import org.opencv.core.Mat;
import org.opencv.core.MatOfByte;
import org.opencv.core.MatOfInt;
import org.opencv.imgcodecs.Imgcodecs;
// 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/
// OpenCV links for creating JPG at given quality
// Convert BufferedImage (Java) to byte array in put to Mat (OpenCV)
// https://stackoverflow.com/a/15095653
// Convert Mat to byte array
// https://stackoverflow.com/a/45960893
// 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[] ocvImageToJPEGByteArray(Image aImage, int width, int height, int qualityPercent) {
if ((qualityPercent < -1) || (qualityPercent > 100)) {
throw new IllegalArgumentException("Quality out of bounds!");
}
//float quality = qualityPercent / 100f;
//OpenCV just needs an int
int quality = qualityPercent;
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_3BYTE_BGR);
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);
//Need to see if we alread have the correct BufferedImage type, if not, convert
if (srcImage.getType() != BufferedImage.TYPE_3BYTE_BGR) {
//http://stackoverflow.com/questions/21740729/converting-bufferedimage-to-mat-opencv-in-java
destImage = new BufferedImage(srcImage.getWidth(), srcImage.getHeight(), BufferedImage.TYPE_3BYTE_BGR);
g = destImage.createGraphics();
g.setComposite(AlphaComposite.Src);
g.drawImage(srcImage, 0, 0, null);
g.dispose();
} else {
destImage = srcImage;
}
}
//Create OpenCV Mat, retrieve data from BufferedImage and assign to Mat
Mat mRGB = new Mat(destImage.getHeight(), destImage.getWidth(), CvType.CV_8UC3);
byte[] pixels = ((DataBufferByte) destImage.getRaster().getDataBuffer()).getData();
mRGB.put(0, 0, pixels);
//Convert mat to JPG byte array of given quality
MatOfByte mob=new MatOfByte(); //Destination Mat byte array
int[] intParams = new int[2]; //Create parameters for imencode
intParams[0] = Imgcodecs.IMWRITE_JPEG_QUALITY;
intParams[1] = (int) quality;
MatOfInt params = new MatOfInt(intParams);
Imgcodecs.imencode(".jpg", mRGB, mob, params);
return mob.toArray(); //Convert Mat byte array to regular byte array
}
#End If
#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];
float quality = 75 / 100f;
BufferedImage destImage;
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("gif");
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, "gif", baos);
}
baos.flush();
imageBytes = baos.toByteArray();
baos.close();
// Done
return imageBytes;
}
#End If