I have been rebuilding the ImageJ library so that it is compatible with android. I am stuck on one of the constructors in PixelGrabber. Bare in mind that I have rebuilt the ImageJ and the awt library so that it takes Bitmap.
My class ColorProcessor constructor
public ColorProcessor(Bitmap img) {
width = img.getWidth();
height = img.getHeight();
pixels = new int[width * height];
PixelGrabber pg = new PixelGrabber(img, 0, 0, width, height, pixels, 0, width);
try {
pg.grabPixels();
} catch (InterruptedException e){};
createColorModel();
fgColor = 0xff000000; //black
resetRoi();
}
Creates an object from PixelGrabber class. Here is the constructor for that.
public PixelGrabber(Bitmap img, int x, int y, int w, int h, int[] pix,
int off, int scansize) {
this(img.getSource(), x, y, w, h, pix, off, scansize);
}
There is a red line under getSource(). This code was designed for the JRE so this getSource is referring to java.awt.Image abstract class. Does anyone know what I can replace img.getSource with?
Any help would be much appreciated.
Related
I cannot seem to figure out how to draw a transparent and rotated image. I need to be able to draw an image that is transparent and rotated to a certain degree.
I tried this code:
// draws an image that is rotated to a certain degree
public static void drawRotatedImage(BufferedImage image_, int x, int y, int degrees, float scale) {
// graphics used for the utilities of drawing the image (processing)
Graphics2D utilGraphics;
// make rectangular image
int radius = (int) Math.sqrt(image_.getWidth() * image_.getWidth() + image_.getHeight() * image_.getHeight());
BufferedImage image1 = new BufferedImage(radius, radius, BufferedImage.TYPE_INT_RGB);
utilGraphics = image1.createGraphics();
// centers image
utilGraphics.drawImage(image_, image1.getWidth() / 2 - image_.getWidth() / 2, image1.getHeight() / 2 - image_.getHeight() / 2, null);
// scale image
int nw = (int) (image1.getWidth() * scale);
int nh = (int) (image1.getHeight() * scale);
BufferedImage image = new BufferedImage(nw, nh, BufferedImage.TYPE_INT_RGB);
utilGraphics.drawImage(image1, 0, 0, nw, nh, null);
// Rotation information
double rotationRequired = Math.toRadians (degrees);
double locationX = image.getWidth() / 2;
double locationY = image.getHeight() / 2;
AffineTransform tx = AffineTransform.getRotateInstance(rotationRequired, locationX, locationY);
AffineTransformOp op = new AffineTransformOp(tx, AffineTransformOp.TYPE_BILINEAR);
ImageProducer filteredImgProd = new FilteredImageSource(op.filter(image, null).getSource(), filter);
Image transparentImg = Toolkit.getDefaultToolkit().createImage(filteredImgProd);
// Drawing the rotated image at the required drawing locations
g2d.drawImage(Toolkit.getDefaultToolkit().createImage(transparentImg.getSource()), x, y, null);
}
The filter variable is defined as:
private static final ImageFilter filter = new RGBImageFilter() {
int transparentColor = new Color(0, 0, 0, 0).getRGB() | 0x0000ffcc;
public final int filterRGB(int x, int y, int rgb) {
if ((rgb | 0x0000ffcc) == transparentColor) {
return 0x0000ffcc & rgb;
} else {
return rgb;
}
}
};
This ...
BufferedImage image = new BufferedImage(nw, nh, BufferedImage.TYPE_INT_RGB);
centeredGraphics.drawImage(image1, 0, 0, nw, nh, null);
You're creating a new BufferedImage (image), but you never actually paint anything to it, instead, you paint image1 to it's own Graphics context.
Now, if you wanted a transparent image, you should have used...
BufferedImage centeredImage = new BufferedImage(radius, radius, BufferedImage.TYPE_INT_ARGB);
instead of...
BufferedImage centeredImage = new BufferedImage(radius, radius, BufferedImage.TYPE_INT_RGB);
And I never used g2d.drawImage(Toolkit.getDefaultToolkit().createImage(transparentImg.getSource()), x, y, null); as it just doesn't make sense to me (transparentImg is already an Image 🤷♂️)
Now, having said all that, I would "suggest" you take each step individually, start by scaling the original image using something like Java: maintaining aspect ratio of JPanel background image and the rotate the image using something like Rotate a buffered image in Java (which will generate a image large enough to contain the rotated image)
Also, if you "create" a Graphics context, you should also dispose of it when you no longer need it, otherwise you could end up with a memory leak.
"Fixed" code...
Just to be clear, I would still recommend sing ARGB instead of RGB for centeredImage as your filter workflow never seemed to work for, but I started with a transparent image anyway
public Image rotateAndScaleImage(BufferedImage originalImage, int degrees, float scale) {
// make rectangular image
int radius = (int) Math.sqrt(originalImage.getWidth() * originalImage.getWidth() + originalImage.getHeight() * originalImage.getHeight());
BufferedImage centeredImage = new BufferedImage(radius, radius, BufferedImage.TYPE_INT_RGB);
Graphics2D graphics = centeredImage.createGraphics();
// centers image
int xPos = (centeredImage.getWidth() - originalImage.getWidth()) / 2;
int yPos = (centeredImage.getHeight() - originalImage.getHeight()) / 2;
graphics.drawImage(originalImage, xPos, yPos, null);
graphics.dispose();
// scale image
int nw = (int) (centeredImage.getWidth() * scale);
int nh = (int) (centeredImage.getHeight() * scale);
BufferedImage image = new BufferedImage(nw, nh, BufferedImage.TYPE_INT_RGB);
graphics = image.createGraphics();
// No scaling is done ???
graphics.drawImage(centeredImage, 0, 0, nw, nh, null);
// Rotation information
double rotationRequired = Math.toRadians(degrees);
double locationX = centeredImage.getWidth() / 2;
double locationY = centeredImage.getHeight() / 2;
AffineTransform tx = AffineTransform.getRotateInstance(rotationRequired, locationX, locationY);
AffineTransformOp op = new AffineTransformOp(tx, AffineTransformOp.TYPE_BILINEAR);
ImageProducer filteredImgProd = new FilteredImageSource(op.filter(centeredImage, null).getSource(), filter);
Image transparentImg = Toolkit.getDefaultToolkit().createImage(filteredImgProd);
return transparentImg;
}
private static final ImageFilter filter = new RGBImageFilter() {
int transparentColor = new Color(0, 0, 0, 0).getRGB() | 0x0000ffcc;
public final int filterRGB(int x, int y, int rgb) {
if ((rgb | 0x0000ffcc) == transparentColor) {
return 0x0000ffcc & rgb;
} else {
return rgb;
}
}
};
Oh, and I'm returning an Image because I painted directly to a component for testing
How can i make my image dynamic; My code :
public void paint(Graphics g){
super.paint(g);
//this.setBackground(Color.white);
g.drawImage(bg,300 , 70, 800, 100, null);
}
That creates an image but when i open the window and i enlarge it; the images takes the right position.
First look at the method you are calling.
drawImage(Image img, int x, int y, int width, int height, ImageObserver observer)
It sounds like you need to know x and y values to paint your image in the correct location. Lets pretend this paint method is inside of a component.
//based on your description.
int imageWidth = 800;
int imageHeight = 100;
int x = (getWidth() - imageWidth)/2;
int y = (getHeight() - imageHeight)/2;
g.drawImage(bg, x, y, imageWidth, imageHeight, this);
That should center your image when the component is resized and repainted. Of course there are better ways to do this, such as using a JLabel and a layout manager.
I am trying to use Tesseract OCR for scanning text in an image. However the background is dark and Tesseract is not able to scan thru for the text.
I need help with java code to clear the background gray color from the image.
I have tried below code, where i set the last parameter, Color, as "COLOR.WHITE" (suggested by someone on this forum but it did not help).
static public BufferedImage scaleImage(BufferedImage img, int width, int height,
Color background) {
int imgWidth = img.getWidth();
int imgHeight = img.getHeight();
if (imgWidth*height < imgHeight*width) {
width = imgWidth*height/imgHeight;
} else {
height = imgHeight*width/imgWidth;
}
BufferedImage newImage = new BufferedImage(width, height,
BufferedImage.TYPE_INT_RGB);
Graphics2D g = newImage.createGraphics();
try {
g.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
RenderingHints.VALUE_INTERPOLATION_BICUBIC);
g.setBackground(background);
g.clearRect(0, 0, width, height);
g.drawImage(img, 0, 0, width, height, null);
} finally {
g.dispose();
}
return newImage;
}
Thanks.
I have this problem. I am using this code to rotate an image but the rotated image has black padding in its corners due to rotation.
How could I remove it?
public static BufferedImage rotate(BufferedImage img, int angle) {
rotate_checked = false;
int w = img.getWidth();
int h = img.getHeight();
BufferedImage dimg =new BufferedImage(w, h, BufferedImage.TYPE_BYTE_GRAY);
Graphics2D g = dimg.createGraphics();
g.rotate(Math.toRadians(angle), w/2, h/2);
g.drawImage(img, null, 0, 0);
return dimg;
}
You need to create a transparent image:
BufferedImage buffer = gc.createCompatibleImage(height, width, Transparency.TRANSLUCENT);
where 'gc' is a Graphics2D object. You can also create one directly with new BufferedImage() of course, but this will give you the most efficient-to-use image for your particular graphics context.
I'm having a problem getting an image to flip. My program is supposed to show the default image and the flipped image. I thought that if I could replace the (0,0) pixel of the flipped picture with the (width-1,height-1) of the original picture, it would work, but instead of getting the original image, I get this.
Here is my code:
import java.awt.Color;
public class Horizontal {
public static void main(String[] args)
{
Picture source = new Picture(args[0]);//name of picture.
Picture flip = new Picture(source.width(), source.height());//sets the width and height of source
for (int i =0; i < source.width(); i++)
{
int w = 1;
int sw = source.width()-w;
for (int j = 0; j < source.width(); j++)
{
int h=1;
int sh = source.height()-h;
Color SourceColor = source.get(sw,sh);// return the the color pixel of (sw,sh)
flip.set(i, j, SourceColor);//suppose to replace the (i,j) pixel of flip with source's (sw,sh) pixel
h++;
}
w++;
}
source.show();// shows the original image
flip.show(); // shows flipped version of image
}
}
Chceck this site. It has great info about basic image algorithms in java.
You can copy code for flipping an image.
http://www.javalobby.org/articles/ultimate-image/#9
Flipping horizontally:
public static BufferedImage horizontalflip(BufferedImage img) {
int w = img.getWidth();
int h = img.getHeight();
BufferedImage dimg = new BufferedImage(w, h, img.getType());
Graphics2D g = dimg.createGraphics();
g.drawImage(img, 0, 0, w, h, w, 0, 0, h, null);
g.dispose();
return dimg;
}
Flipping vertically:
public static BufferedImage verticalflip(BufferedImage img) {
int w = img.getWidth();
int h = img.getHeight();
BufferedImage dimg = dimg = new BufferedImage(w, h, img.getColorModel().getTransparency());
Graphics2D g = dimg.createGraphics();
g.drawImage(img, 0, 0, w, h, 0, h, w, 0, null);
g.dispose();
return dimg;
}