I'm taking screenshot in my runs after every run but want to reduce the size so that it doesn't occupy too much space: every screenshot is 1mb on average, having 200 test with screenshot attached will give 200mb only for screenshots.
Attaching it to allure report
#Attachment
public byte[] attachScreenshot() {
try {
return ((TakesScreenshot) driver).getScreenshotAs(OutputType.BYTES);
} catch (Exception ignore) {return null;}
}
Any ideas on how to shrink the screenshot size?
Finally! Found the solution. My report size went from 70mb to 15mb by compressing to jpg:
private static byte[] pngBytesToJpgBytes(byte[] pngBytes) throws IOException {
//create InputStream for ImageIO using png byte[]
ByteArrayInputStream bais = new ByteArrayInputStream(pngBytes);
//read png bytes as an image
BufferedImage bufferedImage = ImageIO.read(bais);
BufferedImage newBufferedImage = new BufferedImage(bufferedImage.getWidth(),
bufferedImage.getHeight(),
BufferedImage.TYPE_INT_RGB);
newBufferedImage.createGraphics().drawImage(bufferedImage, 0, 0, Color.WHITE, null);
//create OutputStream to write prepaired jpg bytes
ByteArrayOutputStream baos = new ByteArrayOutputStream();
//write image as jpg bytes
ImageIO.write(newBufferedImage, "JPG", baos);
//convert OutputStream to a byte[]
return baos.toByteArray();
}
```
Related
my problem is when using imageio.write i am seeing that is using hdd, also read about jDeli (but too expensive), Apache Commons, JAI that are much faster....
I wanna use the encoded bytes returned by routine... at a custom Remote Desktop Utility...
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;
}
If you are saying that you've observed that this code appears to cause disk activity when saving to ByteArrayOutputStream perhaps you should try setting the ImageIO "use cache" flag to false:
ImageIO.setUseCache(false);
Javadoc for setUseCache says:
Sets a flag indicating whether a disk-based cache file should be used when creating ImageInputStream and ImageOutputStreams.
The problem is that ImageIO.write does not recognize the raw format, so the file does not fill it. I tried the same code with png and it created it correctly. Is there some alternative to ImageIO.write or some other way to create a raw, raw byte file? Is there some conversion alternative for an image in Fid format?
Fid Image to raw
Buffered image to raw
Here I create the file I have indicated the address:
private void RAWCompression(Fid.Fiv imagen) throws IOException{
JFileChooser fileChooser = new JFileChooser(System.getProperty("java.library.path"));
fileChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
fileChooser.setSelectedFile(new File("HuellaRaw.raw"));
fileChooser.showSaveDialog(null);
File dir = fileChooser.getSelectedFile();
File file = new File(dir.getAbsolutePath() + "/" + "HuellaRaw.raw");
System.out.println(file);
//Create file
try {
file.createNewFile();
} catch (IOException ex) {
Logger.getLogger(Capture.class.getName()).log(Level.SEVERE, null, ex);
}
I send the image to buferrtd:
BufferedImage imagenBuffered = new BufferedImage(imagen.getWidth(), imagen.getHeight(), BufferedImage.TYPE_BYTE_GRAY);
imagenBuffered.getRaster().setDataElements(0, 0, imagen.getWidth(), imagen.getHeight(), imagen.getData());
I fill the file and convert it to bytes:
//convert BufferedImage to byte
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ImageIO.write(imagenBuffered, "raw", baos);
byte[] bytes = baos.toByteArray();
//FileUtils.writeByteArrayToFile(file, bytes);
try (FileOutputStream os = new FileOutputStream(file)) {
os.write(bytes);
} catch (Exception e) {
System.err.print("imagen Error wri " + imagen.getImageData() + "\n");
}
This line does not fill the raw file:
(If I change raw to png then it does fill the file.)
ImageIO.write(imagenBuffered, "raw", baos);
This line of code with png is created correctly:
ImageIO.write(imagenBuffered, "png", baos);
You cannot use ImageIO to write raw. You could get the "raw bytes" of your image and write them to a file though.
If you already have your buffered image, you could try the inverse of this answer. https://stackoverflow.com/a/54578326/2067492
int[] rgb = imagenBuffered.getRGB(0, 0, width, height, null, width);
ByteBuffer bb = ByteBuffer.allocate( rgb.length*4 );
bb.asIntBuffer().put(rgb);
bytes = bb.array();
This would write all of the pixels to a byte[], no headers or information about the data, just 4 byte rgba as returned by getRGB.
i need to store on disk a base64 image but i have an error: "Out of memory" when i decode base64 image into byte[]. The size image is about 6MB
This is my code:
byte[] decodedBytes = DatatypeConverter.parseBase64Binary(photo); //HERE I HAVE THE ERROR!!
log.debug("binary ok");
BufferedImage bfi = ImageIO.read(new ByteArrayInputStream(decodedBytes));
String nomeEdata = String.valueOf(Calendar.getInstance().getTimeInMillis() + ".jpg");
String nomeImg = resourceBundle.getString("schede.pathSaveImage") + nomeEdata;
File outputfile = new File(nomeImg);
ImageIO.write(bfi , "png", outputfile);
bfi.flush();
Please, Any suggests?
You could write the "photo" content to a temporary file and then read from it using a Base64InputStream.
In the end, however, the BufferedImage will have the entire raw image in memory. This will require that you have a heap size large enough to accommodate this. You may just have to increase the Xmx value.
final BufferedImage bi = ImageIO.read(new Base64InputStream(new ReaderInputStream(new StringReader(photo), "ascii"));
final File file = ...
final FileOutputStream fos = new FileOutputStream(file);
try
{
ImageIO.write(bi, "png", new Base64OutputStream(fos));
}
finally
{
fos.close();
}
http://commons.apache.org/proper/commons-io/apidocs/org/apache/commons/io/input/ReaderInputStream.html
I am trying to convert Image to Byte Array and save it in database. Image to Byte Conversion and bytes to Image Conversion using ImageIO Method works completely fine before saving it into database. But when i retrieve bytes from Database ImageIO returns null.
FileInputStream fis = new FileInputStream(picturePath);
BufferedImage image = ImageIO.read(new File(picturePath));
BufferedImage img = Scalr.resize(image, Scalr.Mode.FIT_EXACT, 124, 133, Scalr.OP_ANTIALIAS);
ByteArrayOutputStream ByteStream = new ByteArrayOutputStream();
ImageIO.write(img, "jpg", ByteStream);
ByteStream.flush();
byte[] imageBytes = ByteStream.toByteArray();
ByteStream.close();
PersonImage = imageBytes;
ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(PersonImage);
BufferedImage ImageForBox = ImageIO.read((InputStream)byteArrayInputStream);
PersonImageBox.setIcon(new ImageIcon((Image)ImageForBox));
Above code is what I do before saving picture bytes in DB. I resize the Image then convert it into bytes and then convert other way around and show it in JLabel, it works fine. But when I retrieve bytes from database and use the same code i.e.
ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(PersonImage); // PersonImage are bytes from dB.
BufferedImage ImageForBox = ImageIO.read((InputStream)byteArrayInputStream);
PersonImageBox.setIcon(new ImageIcon((Image)ImageForBox));
In this case ImageIO returns null. Please help.
How can I get an InputStream from a BufferedImage object? I tried this but ImageIO.createImageInputStream() always returns NULL
BufferedImage bigImage = GraphicsUtilities.createThumbnail(ImageIO.read(file), 300);
ImageInputStream bigInputStream = ImageIO.createImageInputStream(bigImage);
The image thumbnail is being correctly generated since I can paint bigImage to a JPanel with success.
From http://usna86-techbits.blogspot.com/2010/01/inputstream-from-url-bufferedimage.html
It works very fine!
Here is how you can make an
InputStream for a BufferedImage:
URL url = new URL("http://www.google.com/intl/en_ALL/images/logo.gif");
BufferedImage image = ImageIO.read(url);
ByteArrayOutputStream os = new ByteArrayOutputStream();
ImageIO.write(image, "gif", os);
InputStream is = new ByteArrayInputStream(os.toByteArray());
If you are trying to save the image to a file try:
ImageIO.write(thumb, "jpeg", new File(....));
If you just want at the bytes try doing the write call but pass it a ByteArrayOutputStream which you can then get the byte array out of and do with it what you want.
By overriding the method toByteArray(), returning the buf itself (not copying), you can avoid memory related problems. This will share the same array, not creating another of the correct size. The important thing is to use the size() method in order to control the number of valid bytes into the array.
final ByteArrayOutputStream output = new ByteArrayOutputStream() {
#Override
public synchronized byte[] toByteArray() {
return this.buf;
}
};
ImageIO.write(image, "png", output);
return new ByteArrayInputStream(output.toByteArray(), 0, output.size());