I am trying to include image validation in my test project, so I can validate on some ares of the website as image like teaser, footer..etc
I take a screenshot by selenium and save it as PNG file in the first time, then in every test case I will take a new screenshot and compare both of then by ShutterBug library and print the different.
The main issue that when I take a screenshot each browser has a different size and When I resize it by Graphics2D it will not be the same. I tried also with openCV but it doesn't work. because the anti-aliasing.
private static BufferedImage resize(BufferedImage img, int height, int width, int imageType) throws IOException {
Image tmp = img.getScaledInstance(width, -1, Image.SCALE_SMOOTH);
BufferedImage resized = new BufferedImage(width, height, imageType);
Graphics2D g2d = resized.createGraphics();
g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
g2d.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
g2d.setRenderingHint(RenderingHints.KEY_DITHERING, RenderingHints.VALUE_DITHER_ENABLE);
g2d.drawImage(tmp, 0, 0, null);
g2d.dispose();
return resized;
}
private Mat resize(BufferedImage image, int height, int width){
Size size = new Size(width, height);
Mat img = Imgcodecs.imdecode(new MatOfByte(bufferedImageToByteArray(image)), Imgcodecs.IMREAD_COLOR);
Mat resized=new Mat(size,CvType.CV_64FC4);
Imgproc.resize(img, resized, size,INTER_AREA);
return resized;
}
I have tried all these options but at the end i am now using
https://github.com/newsuk/AyeSpy
Aye Spy is a high performance visual regression tool to catch UI regressions.
It's very simple and manageable.
You just need to setup selenium grid and run the json file.
It will compare perfectly and give you the comparison result like
You can try it one time.Hope it will help you to generate comparison result for testing
There are several open source solutions for comparing screenshots in the UI automation testing, which just does the same things as you are working on. I suggest you can try Micoo which is a visual testing service, self-hosted and open source. When you get used to Micoo, you will find it's quite easy to do visual testing with it, of course, compare with different size of images is not a problem at all.
Related
by using Canvas and JS I can draw a shape like this and have the x,y of each point :
Tha area can be choosen by more than 4 points, look at this link to have an idea.
I need to save and crop the image of the selected area by using the points. I can not use BufferedImage as it is just rectangular. Which lib in java I can use?
Okay, so starting with...
I used...
BufferedImage source = ImageIO.read(new File("Example.jpg"));
GeneralPath clip = new GeneralPath();
clip.moveTo(65, 123);
clip.lineTo(241, 178);
clip.lineTo(268, 405);
clip.lineTo(145, 512);
clip.closePath();
Rectangle bounds = clip.getBounds();
BufferedImage img = new BufferedImage(bounds.width, bounds.height, BufferedImage.TYPE_INT_ARGB);
Graphics2D g2d = img.createGraphics();
clip.transform(AffineTransform.getTranslateInstance(-65, -123));
g2d.setClip(clip);
g2d.translate(-65, -123);
g2d.drawImage(source, 0, 0, null);
g2d.dispose();
ImageIO.write(img, "png", new File("Clipped.png"));
to generate...
Now, the image is rectangular, that's just the way it works
Now, setClip is quite rough and isn't effect by any RenderingHints, you could make use of "soft clipping" instead, which is more involved, but generates a nicer results. See this example and this exmaple for more details
I am currently trying to get some kind of 2D dungeoncrawler (think: roguelike) running. Now I want to work with square tiles (32x32) but I wonder if there's a way to make my textures in a higher resolution, say 64x64, and scale them down onto a 32x32 square?
I imagine there has to be since almost all games do this in one way or another but all I can seem to find online is about 3D stuff.
Yeah. When you draw an image, you can add the new width and height to it to resize it.
public static BufferedImage resizeImage(BufferedImage image, int newwidth, int newheight) {
BufferedImage image2 = new BufferedImage(newwidth, newheight, BufferedImage.TYPE_INT_ARGB);
Graphics g = image2.getGraphics();
g.drawImage(image, 0, 0, newwidth, newheight, null);
g.dispose();
return image2;
}
Refer to here for more info.
I'm working on a simple 2D game, rendering via the Java2D API. I've noticed that when I try to draw on integrated graphics card the performance crashes.
I've tested this game on both my main rig with a newer ATI Radeon and my 5 year old laptop which also has an (incredibly antiquated) Radeon. On both I get good FPS, but when I try to use my Intel i5's onboard HD 4000 graphics, it crawls at around 20 FPS.
I'm using Full Screen Exclusive mode.
At any given moment, I am rendering approximately 1000 images at once.
Annoyingly, when I try to getAvailableAcceleratedMemory() it just returns -1 for this card, and it seems to refuse to accelerate any images.
Does anyone have any ideas how to fix this issue?
Rendering code:
Graphics g = bufferStrategy.getDrawGraphics();
g.drawImage(img, x, y, img.getWidth(), img.getHeight(), null)
g.dispose();
bufferStrategy.show();
Image Loading code:
BufferedImage I = null;
I = ImageIO.read(new File(currentFolder+imgPath));
imgMap.put(imgIdentifier, I);
The images are stored in a hashmap of BufferedImages identified by strings, so when an entity needs to draw and image it just gets it out of the hashmap and draws it. In the current case, the entities are mostly floor and wall tiles, so they never change (and thus don't have to get the image from the hashmap other than the very first time).
EDIT - I've incorporated MadProgrammer's method, but it didn't change my FPS.
This is an example of converting an image to a compatiable image...not an answer in of itself
This is some of the library code that I use...
public static BufferedImage createCompatibleImage(BufferedImage image) {
BufferedImage target = createCompatibleImage(image, image.getWidth(), image.getHeight());
Graphics2D g2d = target.createGraphics();
g2d.drawImage(image, 0, 0, null);
g2d.dispose();
return target;
}
public static BufferedImage createCompatibleImage(BufferedImage image,
int width, int height) {
return getGraphicsConfiguration().createCompatibleImage(width, height, image.getTransparency());
}
public static GraphicsConfiguration getGraphicsConfiguration() {
return GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getDefaultConfiguration();
}
I would do something like...
I = createCompatibleImage(ImageIO.read(new File(currentFolder+imgPath)));
imgMap.put(imgIdentifier, I);
I'm trying to display an Image that is bigger than the JFrame Dimensions. If I try to resize the Image smaller, then the Image quality is lost.
If I make the Image larger, the quality is not lost. Is this normal behavior in Java image package?
I guess what I'm trying to figure out is that probably I'm doing something wrong when reducing the Image size. So does Java provide a method to automatically do this without loosing image quality?
Same behavior like JButtons, where java automatically adjusts the space occupied by a JButton in a JPanel.
bufferedImage = resize(bufImage,500,600);
ImageIcon imageIcon = new ImageIcon(bufferedImage);
resizedIMage = imageIcon.getImage();
The actual resize is below. I took it from the internet.
private static BufferedImage resize(BufferedImage image, int width, int height) {
int type = image.getType() == 0? BufferedImage.TYPE_INT_ARGB : image.getType();
BufferedImage resizedImage = new BufferedImage(width, height, type);
Graphics2D g = resizedImage.createGraphics();
g.setComposite(AlphaComposite.Src);
g.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
RenderingHints.VALUE_INTERPOLATION_BILINEAR);
g.setRenderingHint(RenderingHints.KEY_RENDERING,
RenderingHints.VALUE_RENDER_QUALITY);
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g.drawImage(image, 0, 0, width, height, null);
g.dispose();
return resizedImage;
}
If you are using Java 5 or newer you can try RenderingHints.VALUE_INTERPOLATION_BICUBIC for your interpolation hint.
There is a very detailed description of the different scaling behaviours of Java2D in this article: perils-of-getScaledInstance
It contains examples of the different downscale results you can expect to see with the different approaches available in Java.
It also provides sample code that uses a multi-step aproach to downscale the image which appears to produce much better results than VALUE_INTERPOLATION_BILINEAR.
Override the paintComponent(Graphics g) method of whatever component will display the image and look at Graphics.drawImage()
You can even cast your Graphics instance into a Graphics2D for more functionalities. For example setRenderingHings()
Graphics2D g2 = (Graphics2D) g;
RenderingHints rh = g2.getRenderingHints ();
rh.put (RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g2.setRenderingHints (rh);
I would get rid of this:
int type = image.getType() == 0? BufferedImage.TYPE_INT_ARGB : image.getType();
And always use BufferedImage.TYPE_INT_ARGB
That seems to give me good results.
I am trying to use JAI to perform a rotate task on an image. I can get this working no problem. However, there is severe loss of midtones in the image. The image can be rotated in photoshop without this lack of contrast.
Please see the following 3 images stacked next to each other here, to see what I mean;
http://imgur.com/SYPhZ.jpg
The top image is the original, the middle is rotated in photoshop to prove that it can be done, and the bottom is from the result of my code.
To see the actual images, please see here;
Before rotate: http://imgur.com/eiAOO.jpg
After rotate : http://imgur.com/TTUKS.jpg
You can see the issue most clearly if you load the images in two different tabs, and flick between them.
In terms of code, I load the image as follows;
public void testIt() throws Exception {
File source = new File("c:\\STRIP.jpg");
FileInputStream fis = new FileInputStream(source);
BufferedImage sourceImage = ImageIO.read(fis);
fis.close();
BufferedImage rotatedImage = doRotate(sourceImage, 15);
FileOutputStream output = new FileOutputStream("c:\\STRIP_ROTATED.jpg");
ImageIO.write(rotatedImage, "JPEG", output);
}
and then here is the rotate function;
public BufferedImage doRotate(BufferedImage input, int angle) {
int width = input.getWidth();
int height = input.getHeight();
double radians = Math.toRadians(angle / 10.0);
// Rotate about the input image's centre
AffineTransform rotate = AffineTransform.getRotateInstance(radians, width / 2.0, height / 2.0);
Shape rect = new Rectangle(width, height);
// Work out how big the rotated image would be..
Rectangle bounds = rotate.createTransformedShape(rect).getBounds();
// Shift the rotated image into the centre of the new bounds
rotate.preConcatenate(
AffineTransform.getTranslateInstance((bounds.width - width) / 2.0, (bounds.height - height) / 2.0));
BufferedImage output = new BufferedImage(bounds.width, bounds.height, input.getType());
Graphics2D g2d = (Graphics2D) output.getGraphics();
// Fill the background with white
g2d.setColor(Color.WHITE);
g2d.fill(new Rectangle(width, height));
RenderingHints hints = new RenderingHints(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
hints.put(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setRenderingHints(hints);
g2d.drawImage(input, rotate, null);
return output;
}
This is apparently a bug in JAI that has existed for a while:
The earliest mention that I was able to find of this issue appears here. That original article points to an old jai-core issue here. Having read that resolution, it appears that there is a root bug that is still open and described here.
Whether or not all of that detective work is relevant to your application, it may be possible to construct a color space that is more tolerant than the default that JAI is using for your test code.
In the absolute worst case, you could write the pixel traversal yourself to create a rotated image. That isn't the optimal solution but I mention it for completeness if you absolutely need a solution to this problem today.