How to get the image width from ctx.getPreviousResult().getResponseData() - jmeter

I am writing BeanShell Sampler code in Jmeter for getting image width, which we get from a previous jmeter http request.
byte[] samplerdata=ctx.getPreviousResult().getResponseData();
How can I store the image from the above code, and get the image width and height?

The easiest way is using ImageIO package.
Sample code:
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
byte[] samplerData=ctx.getPreviousResult().getResponseData();
InputStream in = new BufferedInputStream(new ByteArrayInputStream(samplerData));
String mimeType = URLConnection.guessContentTypeFromStream(in);
BufferedImage image = ImageIO.read(in);
int width = image.getWidth();
int height = image.getHeight();
String extension = mimeType.split("/")[1];
File file = new File("image." + extension);
ImageIO.write(image, extension, file);
return "Written image: " + file.getAbsolutePath() + "; width: " + width + "; height: " + height;
It isn't very recommended to use Beanshell for scripting as it has some known performance problems and it may ruin your test in case of severe load.
According to JMeter Best Practices it is better to use JSR223 Test Elements and "groovy" as a language.
See Beanshell vs JSR223 vs Java JMeter Scripting: The Performance-Off You've Been Waiting For! guide for groovy scripting engine installation instructions, scripting best patterns and different scripting engines benchmark.
Don't worry regarding compatibility as valid Java or Beanshell code will be valid Groovy code in 99% of cases.

Related

How can we use existing selenium scripts (java) to get some end to end performance metrics (low load)

I am trying to leverage existing selenium automation scripts in java developed by Automation team to get some end to end performance metrics (total page load time etc) - very minimal load, in parallel to api load testing.
Please let me know what will be the most efficient way to do that. Also i am looking for making minimum changes to the selenium scripts because this will be an ongoing activity with each release and i am looking for to use functional scripts as it is with performance wrapper around it.
Your suggestions will be appreciated.
thank you!
I would avoid using Selenium for load testing. If setting up dedicated perf tests is not an option, you could at least do this:
//Put this into the loaded scripts of your page under test. Make sure loadTimeMs is a global variable or saved to a hidden control.
var loadTimeMs = 0;
var pageContentRecieved = (new Date()).getTime();
$(window).load(function () {
var pageLoaded = (new Date()).getTime();
loadTimeMs = pageLoaded - pageContentRecieved;
});
That will give you an approximate time to load the sync parts of a page. More importantly is the time for the web server to provide you the content. I recommend doing that in a controlled way by calling the page back as an API in the javascript.
//Return previous value for page load time.
JavascriptExecutor je = (JavascriptExecutor)driver;
int pageLoad = je.executeAsyncScript("return loadTimeMs;");
//Goes into Java code.
je = (JavascriptExecutor)driver;
int apiResponseTime = je.executeAsyncScript(
"var loadTimeMs = 0;" +
"var pageContentRecieved = (new Date()).getTime();" +
"$.ajax({url: "demo_test.txt", success: function(result){" +
"var pageLoaded = (new Date()).getTime();" +
"return pageLoaded - pageContentRecieved;" +
"}});" +
);
int fullLoadTime = pageLoad + apiResponseTime;
Finally, add the two values together for a rough/approximate performance check in the middle of your existing selenium tests.

JAVA PDFBox Embed EPS, converted to PDF [duplicate]

I use different tools like processing to create vector plots. These plots are written as single or multi-page pdfs. I would like to include these plots in a single report-like pdf using pdfbox.
My current workflow includes these pdfs as images with the following pseudo code
PDDocument inFile = PDDocument.load(file);
PDPage firstPage = (PDPage) inFile.getDocumentCatalog().getAllPages().get(0);
BufferedImage image = firstPage.convertToImage(BufferedImage.TYPE_INT_RGB, 300);
PDXObjectImage ximage = new PDPixelMap(document, image);
PDPageContentStream contentStream = new PDPageContentStream(document, page);
contentStream.drawXObject(ximage, 0, 0, ximage.getWidth(), ximage.getHeight());
contentStream.close();
While this works it looses the benefits of the vector file formats, espectially file/size vs. printing qualitity.
Is it possible to use pdfbox to include other pdf pages as embedded objects within a page (Not added as a separate page)? Could I e.g. use a PDStream? I would prefer a solution like pdflatex is able to embed pdf figures into a new pdf document.
What other Java libraries can you recommend for that task?
Is it possible to use pdfbox to include other pdf pages as embedded objects within a page
It should be possible. The PDF format allows the use of so called form xobjects to serve as such embedded objects. I don't see an explicit implementation for that, though, but the procedure is similar enough to what PageExtractor or PDFMergerUtility do.
A proof of concept derived from PageExtractor using the current SNAPSHOT of the PDFBox 2.0.0 development version:
PDDocument source = PDDocument.loadNonSeq(SOURCE, null);
List<PDPage> pages = source.getDocumentCatalog().getAllPages();
PDDocument target = new PDDocument();
PDPage page = new PDPage();
PDRectangle cropBox = page.findCropBox();
page.setResources(new PDResources());
target.addPage(page);
PDFormXObject xobject = importAsXObject(target, pages.get(0));
page.getResources().addXObject(xobject, "X");
PDPageContentStream content = new PDPageContentStream(target, page);
AffineTransform transform = new AffineTransform(0, 0.5, -0.5, 0, cropBox.getWidth(), 0);
content.drawXObject(xobject, transform);
transform = new AffineTransform(0.5, 0.5, -0.5, 0.5, 0.5 * cropBox.getWidth(), 0.2 * cropBox.getHeight());
content.drawXObject(xobject, transform);
content.close();
target.save(TARGET);
target.close();
source.close();
This code imports the first page of a source document to a target document as XObject and puts it twice onto a page there with different scaling and rotation transformations, e.g. for this source
it creates this
The helper method importAsXObject actually doing the import is defined like this:
PDFormXObject importAsXObject(PDDocument target, PDPage page) throws IOException
{
final PDStream src = page.getContents();
if (src != null)
{
final PDFormXObject xobject = new PDFormXObject(target);
OutputStream os = xobject.getPDStream().createOutputStream();
InputStream is = src.createInputStream();
try
{
IOUtils.copy(is, os);
}
finally
{
IOUtils.closeQuietly(is);
IOUtils.closeQuietly(os);
}
xobject.setResources(page.findResources());
xobject.setBBox(page.findCropBox());
return xobject;
}
return null;
}
As mentioned above this is only a proof of concept, corner cases have not yet been taken into account.
To update this question:
There is already a helper class in org.apache.pdfbox.multipdf.LayerUtility to do the import.
Example to show superimposing a PDF page onto another PDF: SuperimposePage.
This class is part of the Apache PDFBox Examples and sample transformations as shown by #mkl were added to it.
As mkl appropriately suggested, PDFClown is among the Java libraries which provide explicit support for page embedding (so-called Form XObjects (see PDF Reference 1.7, ยง 4.9)).
In order to let you get a taste of the way PDFClown works, the following code represents the equivalent of mkl's PDFBox solution (NOTE: as mkl later stated, his code sample was by no means optimised, so this comparison may not correspond to the actual status of PDFBox -- comments are welcome to clarify this):
Document source = new File(SOURCE).getDocument();
Pages sourcePages = source.getPages();
Document target = new File().getDocument();
Page targetPage = new Page(target);
target.getPages().add(targetPage);
XObject xobject = sourcePages.get(0).toXObject(target);
PrimitiveComposer composer = new PrimitiveComposer(targetPage);
Dimension2D targetSize = targetPage.getSize();
Dimension2D sourceSize = xobject.getSize();
composer.showXObject(xobject, new Point2D.Double(targetSize.getWidth() * .5, targetSize.getHeight() * .35), new Dimension(sourceSize.getWidth() * .6, sourceSize.getHeight() * .6), XAlignmentEnum.Center, YAlignmentEnum.Middle, 45);
composer.showXObject(xobject, new Point2D.Double(targetSize.getWidth() * .35, targetSize.getHeight()), new Dimension(sourceSize.getWidth() * .4, sourceSize.getHeight() * .4), XAlignmentEnum.Left, YAlignmentEnum.Top, 90);
composer.flush();
target.getFile().save(TARGET, SerializationModeEnum.Standard);
source.getFile().close();
Comparing this code to PDFBox's equivalent you can notice some relevant differences which show PDFClown's neater style (it would be nice if some PDFBox expert could validate my assertions):
Page-to-FormXObject conversion: PDFClown natively supports a dedicated method (Page.toXObject()), so there's no need for additional heavy-lifting such as the helper method importAsXObject();
Resource management: PDFClown automatically (and transparently) allocates page resources, so there's no need for explicit calls such as page.getResources().addXObject(xobject, "X");
XObject drawing: PDFClown supports both high-level (explicit scale, translation and rotation anchors) and low-level (affine transformations) methods to place your FormXObject into the page, so there's no need to necessarily deal with affine transformations.
The whole point is that PDFClown features a rich architecture made up of multiple abstraction layers: according to your requirements, you can choose the most appropriate coding style (either to delve into PDF's low-level basic structures or to leverage its convenient and elegant high-level model). PDFClown lets you tweak every single byte and solve complex tasks with a ridiculously simple method call, at your will.
DISCLOSURE: I'm the lead developer of PDFClown.

MVC3 resize image without losing quality?

Hello everybody I would like to ask how can I resize an image without losing quality?
Here is my controller method
var fileName = DateTime.Now.ToString("MM.dd.yyyy HH.mm.ss") + Path.GetFileName(file.FileName);
var path = Path.Combine(Server.MapPath("~/uploads/"), fileName);
file.SaveAs(path);
System.Drawing.Image img = System.Drawing.Image.FromFile(Server.MapPath("~/uploads/") + fileName);
System.Drawing.Image thumb = img.GetThumbnailImage(97, 114, null, IntPtr.Zero);
img.Dispose();
thumb.Save(Server.MapPath("~/uploads/") + fileName);
There are some really good image resizing libraries out there - I would use one of those. I'm using ImageResizing on one of my projects and the results have been pretty good. Bertrand LeRoy has done some benchmarking of some of the main libraries, which you might find useful.

Why is Wicket not showing correct image on the WebPage?

I have a folder with images: IMG1.jpg, IMG2.jpg, IMG3.jpg, IMG4.jpg.
I do:
BufferedImage _img = null;
_img = ImageIO.read(new File(PATH_TO_IMAGE + "\\IMG"+Id+".jpg")); //where id is the number.
Then the rest...
BufferedDynamicImageResource bufferedDynamicImage = new BufferedDynamicImageResource();
bufferedDynamicImage.setImage(_img);
Image ci = new Image("myImg", bufferedDynamicImage);
add(ci);
And what I get in the end is that although Wicket knows the exact path to some image (which is shown in Log.file) most time it gets random image from my folder. What could be the reason for this?
Following my comment, what about
Image ci = new Image("myImg");
ci.add(AttributeModifier.replace("src", Model.of(PATH_TO_IMAGE + "\\IMG" + Id + ".jpg")));
add(ci);
This changes the src-attribute of your img-tag according to your desired logic, prevents browser-caching where undesired but enables caching where possible.

Rendering smallest possible image size with MVC3 vs Webforms Library

I am in the process of moving a webforms app to MVC3. Ironically enough, everything is cool beans except one thing - images are served from a handler, specifically the Microsoft Generated Image Handler. It works really well - on average a 450kb photo gets output at roughly 20kb.
The actual photo on disk weighs in at 417kb, so i am getting a great reduction.
Moving over to MVC3 i would like to drop the handler and use a controller action. However i seem to be unable to achieve the same kind of file size reduction when rendering the image. I walked through the source and took an exact copy of their image transform code yet i am only achieving 230~kb, which is still a lot bigger than what the ms handler is outputting - 16kb.
You can see an example of both the controller and the handler here
I have walked through the handler source code and cannot see anything that is compressing the image further. If you examine both images you can see a difference - the handler rendered image is less clear, more grainy looking, but still what i would consider satisfactory for my needs.
Can anyone give me any pointers here? is output compression somehow being used? or am i overlooking something very obvious?
The code below is used in my home controller to render the image, and is an exact copy of the FitImage method in the Image Transform class that the handler uses ...
public ActionResult MvcImage()
{
var file = Server.MapPath("~/Content/test.jpg");
var img = System.Drawing.Image.FromFile(file);
var sizedImg = MsScale(img);
var newFile = Server.MapPath("~/App_Data/test.jpg");
if (System.IO.File.Exists(newFile))
{
System.IO.File.Delete(newFile);
}
sizedImg.Save(newFile);
return File(newFile, "image/jpeg");
}
private Image MsScale(Image img)
{
var scaled_height = 267;
var scaled_width = 400;
int resizeWidth = 400;
int resizeHeight = 267;
if (img.Height == 0)
{
resizeWidth = img.Width;
resizeHeight = scaled_height;
}
else if (img.Width == 0)
{
resizeWidth = scaled_width;
resizeHeight = img.Height;
}
else
{
if (((float)img.Width / (float)img.Width < img.Height / (float)img.Height))
{
resizeWidth = img.Width;
resizeHeight = scaled_height;
}
else
{
resizeWidth = scaled_width;
resizeHeight = img.Height;
}
}
Bitmap newimage = new Bitmap(resizeWidth, resizeHeight);
Graphics gra = Graphics.FromImage(newimage);
SetupGraphics(gra);
gra.DrawImage(img, 0, 0, resizeWidth, resizeHeight);
return newimage;
}
private void SetupGraphics(Graphics graphics)
{
graphics.CompositingMode = CompositingMode.SourceCopy;
graphics.CompositingQuality = CompositingQuality.HighSpeed;
graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
graphics.SmoothingMode = SmoothingMode.HighSpeed;
}
If you don't set the quality on the encoder, it uses 100 by default. You'll never get a good size reduction by using 100 due to the way image formats like JPEG work. I've got a VB.net code example of how to set the quality parameter that you should be able to adapt.
80L here is the quality setting. 80 still gives you a fairly high quality image, but at DRASTIC size reduction over 100.
Dim graphic As System.Drawing.Graphics = System.Drawing.Graphics.FromImage(newImage)
graphic.InterpolationMode = Drawing.Drawing2D.InterpolationMode.HighQualityBicubic
graphic.SmoothingMode = Drawing.Drawing2D.SmoothingMode.HighQuality
graphic.PixelOffsetMode = Drawing.Drawing2D.PixelOffsetMode.HighQuality
graphic.CompositingQuality = Drawing.Drawing2D.CompositingQuality.HighQuality
graphic.DrawImage(sourceImage, 0, 0, width, height)
' now encode and send the new image
' This is the important part
Dim info() As Drawing.Imaging.ImageCodecInfo = Drawing.Imaging.ImageCodecInfo.GetImageEncoders()
Dim encoderParameters As New Drawing.Imaging.EncoderParameters(1)
encoderParameters.Param(0) = New Drawing.Imaging.EncoderParameter(Drawing.Imaging.Encoder.Quality, 80L)
ms = New System.IO.MemoryStream
newImage.Save(ms, info(1), encoderParameters)
When you save or otherwise write the image after setting the encoder parameters, it'll output it using the JPEG encoder (in this case) set to quality 80. That will get you the size savings you're looking for.
I believe it's defaulting to PNG format also, although Tridus' solution solves that also.
However, I highly suggest using this MVC-friendly library instead, as it avoids all the image resizing pitfalls and doesn't leak memory. It's very lightweight, free, and fully supported.

Resources