I want to get a region of interest (ROI) from an SWT Image object.
I am unable to find a method that will do this for me. Is it possible to avoid writing one by myself?
I need something like (similar to opencv implementations):
Image img = new Image(display, path);
Rectangle roi = new Rectangle(0, 0, 10, 10);
Image imgRoi = img.getROI(roi);
I'm not aware of a base SWT method to create images from a region, but I found a snippet that should do that here https://gist.github.com/azhawkes/4347761 (credits goes to the author Andy Hawkes).
Here I slightly modified the method to get in input the original image. I also implemented an optimization suggested by greg-449 (minimized the calls to Image.getImageData).
public static Image loadImageFromRegion(Image original, Rectangle region) {
ImageData originalImageData = original.getImageData();
ImageData data = new ImageData(region.width, region.height, originalImageData.depth, originalImageData.palette);
int[] pixels = new int[region.width];
byte[] alphas = new byte[region.width];
for (int y = 0; y < region.height; y++) {
originalImageData.getAlphas(region.x, region.y + y, region.width, alphas, 0);
originalImageData.getPixels(region.x, region.y + y, region.width, pixels, 0);
data.setPixels(0, y, region.width, pixels, 0);
data.setAlphas(0, y, region.width, alphas, 0);
}
return new Image(Display.getCurrent(), data);
}
Related
Using iText, exactly how are objects like rectangles and stamp annotations rotated?
I've seen some examples on how to rotate annotations using current transformation matrix and using appearance matrix. You can see my implementation in the below code.
I've tried with different values for appearance matrix, it doesn't seem to be solving or fitting the image as I've expected.
My use-case is I have X, Y, width, height and rotation angle(+or-45, +or- 90 etc.,) of the location I need to fit in the image.
I'm able to rotate the image but I would like the image to fit in the dimensions I've given.
For example check this DOCUMENT , it is generated with -45 degree with rectangle height and width are 400, 250. The rotation seems ok but the image didn't fit in the dimensions I've given.
I would like to rotate the image based on the (X,Y) as axis and would really be glad if someone helped out.
public static void addStampAnnotation(File file) throws Exception
{
PdfReader reader1 = new PdfReader(file);
ByteArrayOutputStream mos = new ByteArrayOutputStream();
PdfDocument docc = new PdfDocument(reader1, new PdfWriter(mos),new StampingProperties().useAppendMode());
String filePath = "rectangle.png";
ImageData img = ImageDataFactory.create(filePath);
// img.setRotation(90);
Rectangle rect=null;
float w = img.getWidth();
float h = img.getHeight();
rect = new Rectangle(0,0, 250,400);
PdfFormXObject xObj = new PdfFormXObject(new Rectangle(w,h));
PdfCanvas canvas = new PdfCanvas(xObj, docc);
canvas.addImageAt(img,0,0,false);
// canvas.addImageWithTransformationMatrix(img, w, 0, 0, h, 0, 0);
xObj.put(PdfName.Matrix, new PdfArray(new int[]{0, 1, -1, 0, 0, 0}));
PdfStampAnnotation stamp = new PdfStampAnnotation(rect);
stamp.setNormalAppearance(xObj.getPdfObject());
int flag = PdfAnnotation.PRINT ;
stamp.setFlags(flag);
docc.getPage(1).addAnnotation(stamp);
docc.close();
file = new File("Test_Doc.pdf");
FileOutputStream fout1 = new FileOutputStream(file);
fout1.write(mos.toByteArray());
fout1.close();
}
The image used is here IMAGE
Thanks in advance !
I have a Bitmap drawn in a rectangle. I want to rotate the Bitmap to 90 degree and draw the oriented Bitmap in the same rectangle bound, for that I may need to scale it.
Above the oriented image is not scaled to fit the rectangle bound of original rectangle (see the first image, the normal one) and also it does remove the lower part of the image. Below is code snippet. Any suggestion ?
sourceImageRect.left = 0;
sourceImageRect.top = 0;
sourceImageRect.right = bmp.getWidth();
sourceImageRect.bottom = bmp.getHeight();
destImageRect.top = destTop;
destImageRect.left = destLeft;
destImageRect.right = destLeft + destWidth;
destImageRect.bottom = destTop + destHeight;
canvas.save(Canvas.MATRIX_SAVE_FLAG);
canvas.rotate(90, (destLeft + (destWidth / 2)),
(destTop + (destHeight / 2)));
canvas.drawBitmap(bmp, sourceImageRect, destImageRect, null);
canvas.restore();
Last image is exact required output I need.
I writed a tool java class named ImageScaleUtil.java several days ago. Helping you can get some useful information on it.
You can use it, like this:
```java
Bitmap targetBitmap = ImageScaleUtil.getScaleBitmap(Bitmap sourceBitmap, int reqWidth, int reqHeight);
```
As of #pskink pastebin reference, following way I resolved and it's working code,
Matrix matrix = new Matrix();
matrix.postRotate(90);
Bitmap bmpRotated = Bitmap.createBitmap(bmpSource, 0, 0, bmpSource.getWidth(), bmpSource.getHeight(), matrix, true);
sourceImageRect.left = 0;
sourceImageRect.top = 0;
sourceImageRect.right = bmpRotated.getWidth();
sourceImageRect.bottom = bmpRotated.getHeight();
destImageRect.top = destTop;
destImageRect.left = destLeft;
destImageRect.right = destLeft + destWidth;
destImageRect.bottom = destTop + destHeight;
canvas.drawBitmap(bmpRotated, sourceImageRect, destImageRect, null);
However, I managed to create Bitmap outside of OnDraw()
I want to convert my picture from colored to Black and white which seems to be created from scratch.
Here is the code which i tried as described on the different post:
BufferedImage bi = ImageIO.read(new File("/Users/***/Documents/Photograph.jpg"));
ColorConvertOp op =
new ColorConvertOp(ColorSpace.getInstance(ColorSpace.CS_GRAY), null);
ImageIO.write(bi, "PNG", new File("/Users/bng/Documents/rendered2.png"));
op.filter(bi, bi);
But still my image is not converted to the Black and white. Additionally, this code is increasing the rendered2.png image size to 10 folds.
Also, it would be great if i could find some Java 8 way of doing this.
Any suggestions?
Here is the code which worked for me:
BufferedImage input = ImageIO.read(new File("/Users/bng/Documents/Photograph.jpg"));
// Create a black-and-white image of the same size.
BufferedImage im = new BufferedImage(input.getWidth(), input.getHeight(), BufferedImage.TYPE_BYTE_BINARY);
// Get the graphics context for the black-and-white image.
Graphics2D g2d = im.createGraphics();
// Render the input image on it.
g2d.drawImage(input, 0, 0, null);
// Store the resulting image using the PNG format.
ImageIO.write(im, "PNG", new File("/Users/bng/Documents/rendered.png"));
It was BufferedImage.TYPE_BYTE_BINARY which provided me the exact solution.
Lokking for the Java 8 Version for above code.
You have to find RGB of the existing colors of the image you want to change it.
Fyi, you want to change it as white RGB value is (255,255,255) and for black RGB value is (0,0,0)
Following method easily do the color change if you apply correct way of your requirement
private BufferedImage changeColor(BufferedImage image, int srcColor, int replaceColor)
{
BufferedImage destImage = new BufferedImage(image.getWidth(), image.getHeight(), BufferedImage.TYPE_INT_ARGB);
Graphics2D g = destImage.createGraphics();
g.drawImage(image, null, 0, 0);
g.dispose();
for (int width = 0; width < image.getWidth(); width++)
{
for (int height = 0; height < image.getHeight(); height++)
{
if (destImage.getRGB(width, height) == srcColor)
{
destImage.setRGB(width, height, replaceColor);
}
}
}
return destImage;
}
you have to use the ColorConvertOp in a proper way:
create Source image
apply filter
save dest
example:
BufferedImage src = ImageIO.read(new File("/Users/***/Documents/Photograph.jpg"));
ColorConvertOp op =
new ColorConvertOp(ColorSpace.getInstance(ColorSpace.CS_GRAY), null);
BufferedImage dest = op.filter(src, null);
ImageIO.write(dest, "PNG", new File("/Users/bng/Documents/rendered2.png"));
src:
dest:
I need a way to find an image on the screen. I've searched for ways to do this on SO but some take extremely long. I need it to be fast and efficient, does not need to be accurate. Basically i'm planning to compare or search for a small pixelated image, say 11x10 pixels for example, on the screen.
I also need a way to know the x and y coordinates of the small image on the screen.
Although I've looked through many tools out there like JavaCV and OpenCV, I just wanted to see if there are any other ways to do this.
TL;DR
I need a fast way to search for a small (11x10 example.) image on the screen and know its x,y coordinates.
I think you many find this answer relevant! But it is for Windows & in c++. But i'm sure that you can convert it very easily to any language.
This question is very old, But im trying to acheive the exact same thing here. Ive found that combining these answers would do the trick:
Convert BufferedImage TYPE_INT_RGB to OpenCV Mat Object
OpenCV Template Matching example in Android
The reason you need to do a conversion is because when u grab a screenshot with awt.Robot class its in the INT_RGB format. The matching template example expects bytes and you cannot grab byte data from this type of image directly.
Heres my implementation of these two answers, but it is incomplete. The output is all screwed up and i think it may have something to do with the IntBuffer/ByteBuffers.
-Edit-
I've added a new helper method that converts a INT_RGB to a BYTE_BGR. I can now grab the coordinates of template on the image using matchLoc.This seems to work pretty well, I was able to use this with a robot that clicks the start menu for me based on the template.
private BufferedImage FindTemplate() {
System.out.println("\nRunning Template Matching");
int match_method = Imgproc.TM_SQDIFF;
BufferedImage screenShot = null;
try {
Robot rob = new Robot();
screenShot = rob.createScreenCapture(new Rectangle(Toolkit.getDefaultToolkit().getScreenSize()));
} catch (AWTException ex) {
Logger.getLogger(MainGUI.class.getName()).log(Level.SEVERE, null, ex);
}
if(screenShot == null) return;
Mat img = BufferedImageToMat(convertIntRGBTo3ByteBGR(screenShot));
String templateFile = "C:\\Temp\\template1.JPG";
Mat templ = Highgui.imread(templateFile);
// / Create the result matrix
int result_cols = img.cols() - templ.cols() + 1;
int result_rows = img.rows() - templ.rows() + 1;
Mat result = new Mat(result_rows, result_cols, CvType.CV_32FC1);
// / Do the Matching and Normalize
Imgproc.matchTemplate(img, templ, result, match_method);
Core.normalize(result, result, 0, 1, Core.NORM_MINMAX, -1, new Mat());
Highgui.imwrite("out2.png", result);
// / Localizing the best match with minMaxLoc
MinMaxLocResult mmr = Core.minMaxLoc(result);
Point matchLoc;
if (match_method == Imgproc.TM_SQDIFF
|| match_method == Imgproc.TM_SQDIFF_NORMED) {
matchLoc = mmr.minLoc;
} else {
matchLoc = mmr.maxLoc;
}
Graphics2D graphics = screenShot.createGraphics();
graphics.setColor(Color.red);
graphics.setStroke(new BasicStroke(3));
graphics.drawRect(matchLoc.x, matchLoc.y, templ.width(), templ.height());
graphics.dispose();
return screenShot;
}
private Mat BufferedImageToMat(BufferedImage img){
int[] data = ((DataBufferInt) img.getRaster().getDataBuffer()).getData();
ByteBuffer byteBuffer = ByteBuffer.allocate(data.length * 4);
IntBuffer intBuffer = byteBuffer.asIntBuffer();
intBuffer.put(data);
Mat mat = new Mat(img.getHeight(), img.getWidth(), CvType.CV_8UC3);
mat.put(0, 0, byteBuffer.array());
return mat;
}`
private BufferedImage convertIntRGBTo3ByteBGR(BufferedImage img){
BufferedImage convertedImage = new BufferedImage(img.getWidth(), img.getHeight(), BufferedImage.TYPE_3BYTE_BGR);
Graphics2D graphics = convertedImage.createGraphics();
graphics.drawImage(img, 0, 0, null);
graphics.dispose();
return convertedImage;
}
Results:
Template:
With a URL of a PNG image (or the data at that url, in String form), how could one use Java to find the RGB (or similar) value at a set of coordinates?
Thanks in advance!
This example should have all you need:
http://www.daniweb.com/software-development/java/threads/114513
To cite the relevant part of the thread:
File inputFile = new File("image.png");
BufferedImage bufferedImage = ImageIO.read(inputFile);
int w = bufferedImage.getWidth();
int h = bufferedImage.getHeight(null);
//Get Pixels
int [] rgbs = new int[w*h];
bufferedImage.getRGB(0, 0, w, h, rgbs, 0, w); //Get all pixels
and then to get a particular pixel, see the docs:
http://docs.oracle.com/javase/6/docs/api/java/awt/image/BufferedImage.html#getRGB(int,%20int,%20int,%20int,%20int%91%93,%20int,%20int)
i.e.:
int pixel = rgbs[offset + (y-startY)*scansize + (x-startX)];
If you just want one pixel, you can use getRGB(x, y):
http://docs.oracle.com/javase/6/docs/api/java/awt/image/BufferedImage.html#getRGB(int,%20int)
i.e.:
int pixel = bufferedImage.getRGB(x, y);