Ashot Java Heap Space Errors - java

I want to run a parralel screenshot testing, but have got an error.
I raised Xmx and Xms up, they are not eating all my RAM, which I have a 32gb.
But they fails at random point after eating it's defined memory.
Have there any solution for memory optimization ?
I comapare somewhere 18+ images which in PNG format takes nearby 200-600-800kb
This is gradle.properties.
org.gradle.parallel=false
org.gradle.caching=false
org.gradle.console=verbose
org.gradle.jvmargs=-Xmx16g -Xms4g -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
systemProp.junit.jupiter.execution.parallel.enabled=true
systemProp.junit.jupiter.execution.parallel.mode.default=concurrent
systemProp.junit.jupiter.execution.parallel.mode.classes.default=concurrent
systemProp.junit.jupiter.execution.parallel.config.strategy=dynamic
systemProp.junit.jupiter.execution.parallel.config.dynamic.factor=1
My imports, there is latest versions of the libs.
import ru.yandex.qatools.ashot.AShot;
import ru.yandex.qatools.ashot.Screenshot;
import ru.yandex.qatools.ashot.comparison.ImageDiff;
import ru.yandex.qatools.ashot.comparison.ImageDiffer;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
And some code with I find diff
protected int differenceBetweenPages(String pageName,
String actualUrl,
int scrollTime) throws IOException {
open(actualUrl);
actual = capturePage(scrollTime);
ImageIO.write(actual.getImage(), "png", actualImg(pageName));
attach = new FileInputStream(actualImg(pageName));
Allure.addAttachment("Actual page", "image/png", attach, ".png");
attach.close();
expected = expectedScreenshot(pageName);
diff = new ImageDiffer().makeDiff(expected, actual);
ImageIO.write(diff.getMarkedImage(), "png", diffImg(pageName));
attach = new FileInputStream(diffImg(pageName));
Allure.addAttachment("Diff Page", "image/png", attach, ".png");
attach.close();
return diff.getDiffSize();
}

I also had issues using Ashot library. I switched to ShutterBug instead and it's working fine.
https://github.com/assertthat/selenium-shutterbug
build.gradle snippet
compile 'com.assertthat:selenium-shutterbug:0.9.2'
API to capture the page screenshot and attach it to the Allure Report
#Attachment(value = "Page screenshot", type = "image/png")
public static byte[] captureScreenshot(WebDriver driver) {
BufferedImage screenshot = Shutterbug.shootPage(driver, ScrollStrategy.WHOLE_PAGE, true).getImage();
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
try {
ImageIO.write(screenshot, "png", outputStream);
} catch (IOException e) {
e.printStackTrace();
}
return outputStream.toByteArray();
}

Related

Oracle Apex, Apache PDFBox java stored procedure issues

Some background: in my app, there are some pdf reports. But, these pdf reports need to be "image" based and I was told that the report server is unable to do this. The call to the report server is done from a pl/sql procedure and the result is a blob, so now all I have at my disposal to try to do this conversion is a java stored procedure. Here is what I came up with (using Apache PDFBox):
create or replace and compile java source named "APDFUtil"
as
import oracle.sql.*;
import oracle.jdbc.driver.*;
import java.sql.*;
import oracle.sql.BLOB;
import java.sql.Blob;
import javax.imageio.ImageIO;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.io.*;
import java.util.*;
import javax.imageio.ImageIO;
import org.apache.pdfbox.pdmodel.*;
import org.apache.pdfbox.rendering.*;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.common.PDRectangle;
import org.apache.pdfbox.pdmodel.graphics.image.LosslessFactory;
import org.apache.pdfbox.pdmodel.graphics.image.PDImageXObject;
import org.apache.pdfbox.rendering.PDFRenderer;
import org.apache.pdfbox.tools.imageio.ImageIOUtil;
import java.awt.image.BufferedImage;
public class APDFUtil{
static OracleDriver ora = new OracleDriver();
static Connection conn;
static ByteArrayOutputStream out;
static {
try {
conn = ora.defaultConnection();
} catch (Exception ex) {}
}
public static oracle.sql.BLOB flattenPDF (oracle.sql.BLOB value) throws Exception {
if (conn == null) conn = ora.defaultConnection();
BLOB retBlob = BLOB.createTemporary(conn, true, oracle.sql.BLOB.DURATION_SESSION);
/*BEGIN TO_JPG*/
InputStream inputStream = value.getBinaryStream();
PDDocument document = PDDocument.load(inputStream);
PDFRenderer pdfRenderer = new PDFRenderer(document);
int noOfPages = document.getNumberOfPages();
BufferedImage[] pdfJPEG = new BufferedImage[noOfPages];
for (int page = 0; page < noOfPages; ++page) {
BufferedImage bim = pdfRenderer.renderImageWithDPI(page, 300, ImageType.RGB);
pdfJPEG[page] = bim;
}
/*write images to new pdf*/
PDDocument documentOut = new PDDocument();
for (int page = 0; page < noOfPages;++page) {
/*get page from old document to determine width and height*/
PDPage oldPage = document.getPage(page);
Float pw = oldPage.getMediaBox().getWidth();
Float ph = oldPage.getMediaBox().getHeight();
PDRectangle rec = new PDRectangle(pw,ph);
PDPage newPage = new PDPage(rec);
documentOut.addPage(newPage);
PDImageXObject pdImage = LosslessFactory.createFromImage(documentOut, pdfJPEG[page]);
PDPageContentStream contents = new PDPageContentStream(documentOut, newPage);
contents.drawImage(pdImage, 0, 0,pw,ph);
contents.close();
}
ByteArrayOutputStream out = new ByteArrayOutputStream();
documentOut.save(out);
documentOut.close();
document.close();
/*END OF TO_JPG*/
/*out - we used to get this back from TO_JPG*/
try {
java.io.OutputStream outStr = retBlob.setBinaryStream(0);
outStr.write(out.toByteArray());
outStr.flush();
} finally {
out.close();
}
return retBlob;
}
}
the pdfbox jars have been loaded into the database
database is oracle 19c standard edition 2 release 19.0.0.0.0
I tried this code as a standalone java project with the exception that the pdf file is being read from the disk, and new file written to the disk and there it works flawlessly.
The issue:
I believe the problem starts at this line: BufferedImage bim = pdfRenderer.renderImageWithDPI(page, 300, ImageType.RGB);
but I don't know what is causing the error or how to debug it (I came to this conclusion by a painstaking process of elimination of code and throwing exceptions) especially since it works in a standalone project. Java stored procedures are not a specialty of mine and this code was pieced together from many different sources online.

Sending Java InputStream to Linux Commands as a File Parameter

Recently I have got involved into Storlet project which is a middleware of OpenStack Swift Project. I do not intend to talk about Storlet but, in short Storlet running a java code on objects(files) that stored into swift object storage. Files read by the storlet and send to the java application in form of InputSream which means we don't direct access to files.
this is a sample code of a storlet which gets the image as an inputstream and make a thumbnail of it.
import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.io.InputStream;
import java.io.OutputStream;
import org.openstack.storlet.common.IStorlet;
import org.openstack.storlet.common.StorletException;
import org.openstack.storlet.common.StorletInputStream;
import org.openstack.storlet.common.StorletLogger;
import org.openstack.storlet.common.StorletObjectOutputStream;
import org.openstack.storlet.common.StorletContainerHandle;
import org.openstack.storlet.common.StorletOutputStream;
import org.openstack.storlet.common.StorletUtils;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.awt.Image;
import java.awt.Transparency;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
public class ThumbnailStorlet implements IStorlet {
#Override
public void invoke(ArrayList<StorletInputStream> inputStreams,
ArrayList<StorletOutputStream> outputStreams,
Map<String, String> parameters, StorletLogger log)
throws StorletException {
log.emitLog("ThumbnailStorlet Invoked");
/*
* Get input stuff
*/
HashMap<String, String> object_md;
StorletInputStream storletInputStream = inputStreams.get(0);
InputStream thumbnailInputStream = storletInputStream.getStream();
object_md = storletInputStream.getMetadata();
/*
* Get output stuff
*/
StorletObjectOutputStream storletObjectOutputStream = (StorletObjectOutputStream)outputStreams.get(0);
OutputStream thumbnailOutputStream = storletObjectOutputStream.getStream();
/*
* Set the output metadata
*/
log.emitLog("Setting metadata");
storletObjectOutputStream.setMetadata(object_md);
/*
* Read Input to BufferedImage
*/
log.emitLog("Reading Input");
BufferedImage img = null;
try {
img = ImageIO.read(thumbnailInputStream);
} catch (Exception e) {
log.emitLog("Failed to read input stream to buffered image");
throw new StorletException("Failed to read input stream to buffered image " + e.getMessage());
} finally {
try {
thumbnailInputStream.close();
} catch (IOException e) {
log.emitLog("Failed to close input stream");
}
}
try {
thumbnailInputStream.close();
} catch (IOException e) {
log.emitLog("Failed to close input stream");
}
/*
* Convert
*/
log.emitLog("Converting");
int newH = img.getHeight()/8;
int newW = img.getWidth()/8;
int type = img.getTransparency() == Transparency.OPAQUE ? BufferedImage.TYPE_INT_RGB : BufferedImage.TYPE_INT_ARGB;
BufferedImage thumbnailImage = new BufferedImage(newW, newH, type);
Graphics2D g = thumbnailImage.createGraphics();
g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
g.drawImage(img, 0, 0, newW, newH, null);
g.dispose();
/*
* Write
*/
log.emitLog("Writing Output");
try {
ImageIO.write(thumbnailImage, "PNG" , thumbnailOutputStream);
} catch (Exception e) {
log.emitLog("Failed to write image to out stream");
throw new StorletException("Failed to write image to out stream " + e.getMessage());
} finally {
try {
thumbnailOutputStream.close();
} catch (IOException e) {
}
}
try {
thumbnailOutputStream.close();
} catch (IOException e) {
}
log.emitLog("Done");
}
}
Now ..
I want to using some external application which running on images such as GDAL inside my java code ,assume code like the code above(not exactly doing the same as above). GDLA has some cli commands. For example this command
gdal_translate -of JPEG -co QUALITY=50 input.tif output.jpg
The input.tif has already stored into my object storage and storlet can read it and give it to me as inputstream, also I have some practice how to run external process inside java with java ProcessBuilder but, imagine I receive input.tif as InputStream not a file.
Next, I don't want to write back InputStream to local storage where my application running there because of lack of storage ( maybe the object are very large, more the 2GBs) and also degrading performance.
Is there any way in java to pass InputStream to external process as a file argument without storing it on disk.
I am running my code on Ubuntu Docker
I donĀ“t think you can do that, a File needs to be stored in a File system (either local or remote) to be read. You could try to base a ByteArrayInputStream to the reading process but the GDAL process should support that type of input:
https://gdal.org/programs/gdal_translate.html#cmdoption-gdal_translate-arg-src_dataset
As per the GDAL documentation, it does not seem possible:
<src_dataset>
The source dataset name. It can be either file name, URL of data source or subdataset name for multi-dataset files.

How to take screenshots and paste it in a word file one by one using webDriver (java)

I am able to take screenshot by ((TakesScreenshot)driver).getScreenshotAs(OutputType.FILE);
In my application I have to take screenshot for every page so I want to save the multiple screenshot into a single .doc file one by one.
Is there any API?
Any Idea?
Please Help...
Easiest way - take screenshot, put it in PNG/JPEG file, read it, add it in MS-Word, delete the file, simple. here's a ready to use code for you.... BINGO...!!
import java.awt.Rectangle;
import java.awt.Robot;
import java.awt.Toolkit;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.util.concurrent.TimeUnit;
import javax.imageio.ImageIO;
import org.apache.poi.util.Units;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.apache.poi.xwpf.usermodel.XWPFRun;
public class TakeScreenshots {
public static void main(String[] args) {
try {
XWPFDocument docx = new XWPFDocument();
XWPFRun run = docx.createParagraph().createRun();
FileOutputStream out = new FileOutputStream("d:/xyz/doc1.docx");
for (int counter = 1; counter <= 5; counter++) {
captureScreenShot(docx, run, out);
TimeUnit.SECONDS.sleep(1);
}
docx.write(out);
out.flush();
out.close();
docx.close();
} catch (Exception e) {
e.printStackTrace();
}
}
public static void captureScreenShot(XWPFDocument docx, XWPFRun run, FileOutputStream out) throws Exception {
String screenshot_name = System.currentTimeMillis() + ".png";
BufferedImage image = new Robot()
.createScreenCapture(new Rectangle(Toolkit.getDefaultToolkit().getScreenSize()));
File file = new File("d:/xyz/" + screenshot_name);
ImageIO.write(image, "png", file);
InputStream pic = new FileInputStream("d:/xyz/" + screenshot_name);
run.addBreak();
run.addPicture(pic, XWPFDocument.PICTURE_TYPE_PNG, screenshot_name, Units.toEMU(350), Units.toEMU(350));
pic.close();
file.delete();
}
}
Selenium Webdriver do not provide any feature to add snapshot in word file.
For this you need to use third party libraries.
Refer below:-
how to insert image into word document using java
How can I add an Image to MSWord document using Java
You can also add your image file in TestNG output file using reporter
Refer below :-
http://www.automationtesting.co.in/2010/07/testng-take-screenshot-of-failed-test.html
Hope it will help you :)

Error Loading Main Class in Java in Windows Command Prompt

I am trying to run an image compression code in Java, and after a long time I am not using an IDE to do so, and am running the code from windows cmd itself.
Here's my code:
import java.io.*;
import java.util.*;
import java.awt.image.*;
import javax.imageio.*;
import javax.imageio.stream.ImageOutputStream;
public class Compression {
public static void main(String[] args) throws IOException {
File input = new File("digital_image_processing.jpg");
BufferedImage image = ImageIO.read(input);
File compressedImageFile = new File("compress.jpg");
OutputStream os =new FileOutputStream(compressedImageFile);
Iterator<ImageWriter>writers = ImageIO.getImageWritersByFormatName("jpg");
ImageWriter writer = (ImageWriter) writers.next();
ImageOutputStream ios = ImageIO.createImageOutputStream(os);
writer.setOutput(ios);
ImageWriteParam param = writer.getDefaultWriteParam();
param.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
param.setCompressionQuality(0.05f);
writer.write(null, new IIOImage(image, null, null), param);
os.close();
ios.close();
writer.dispose();
}
}
In cmd I am in the directory where the Compression.java is present.
This is what is happening:
Any suggestions? I have tried all the suggestions given on Stack on similar questions but none of them seem to work for me.
Assuming you showed the full code, your class is not in a package, so that's not the issue.
Your issue is likely that the current directory is not in the classpath, by default. Check it with this command:
set CLASSPATH
To run your code directly, use:
java -cp . Compression
This will run Java with the current directory as the only path in the classpath.

How to setup zxing library on Windows 8 machine?

I have images of codes that I want to decode. How can I use zxing so that I specify the image location and get the decoded text back, and in case the decoding fails (it will for some images, that's the project), it gives me an error.
How can I setup zxing on my Windows machine? I downloaded the jar file, but I don't know where to start. I understand I'll have to create a code to read the image and supply it to the library reader method, but a guide how to do that would be very helpful.
I was able to do it. Downloaded the source and added the following code. Bit rustic, but gets the work done.
import com.google.zxing.NotFoundException;
import com.google.zxing.ChecksumException;
import com.google.zxing.FormatException;
import com.google.zxing.BarcodeFormat;
import com.google.zxing.DecodeHintType;
import com.google.zxing.Reader;
import com.google.zxing.BinaryBitmap;
import com.google.zxing.Result;
import com.google.zxing.LuminanceSource;
import com.google.zxing.client.j2se.BufferedImageLuminanceSource;
import com.google.zxing.common.HybridBinarizer;
import java.awt.image.BufferedImage;
import javax.imageio.ImageIO;
import java.io.File;
import java.io.IOException;
import java.util.*;
import com.google.zxing.qrcode.QRCodeReader;
class qr
{
public static void main(String args[])
{
Reader xReader = new QRCodeReader();
BufferedImage dest = null;
try
{
dest = ImageIO.read(new File(args[0]));
}
catch(IOException e)
{
System.out.println("Cannot load input image");
}
LuminanceSource source = new BufferedImageLuminanceSource(dest);
BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));
Vector<BarcodeFormat> barcodeFormats = new Vector<BarcodeFormat>();
barcodeFormats.add(BarcodeFormat.QR_CODE);
HashMap<DecodeHintType, Object> decodeHints = new HashMap<DecodeHintType, Object>(3);
decodeHints.put(DecodeHintType.POSSIBLE_FORMATS, barcodeFormats);
decodeHints.put(DecodeHintType.TRY_HARDER, Boolean.TRUE);
Result result = null;
try
{
result = xReader.decode(bitmap, decodeHints);
System.out.println("Code Decoded");
String text = result.getText();
System.out.println(text);
}
catch(NotFoundException e)
{
System.out.println("Decoding Failed");
}
catch(ChecksumException e)
{
System.out.println("Checksum error");
}
catch(FormatException e)
{
System.out.println("Wrong format");
}
}
}
The project includes a class called CommandLineRunner which you can simply call from the command line. You can also look at its source to see how it works and reuse it.
There is nothing to install or set up. It's a library. Typically you don't download the jar but declare it as a dependency in your Maven-based project.
If you just want to send an image to decode, use http://zxing.org/w/decode.jspx

Categories