Drawing new image over old image java - java

I need to draw a new image over old image. I first opened both images in BufferedImage and changed their white background to transparent. Then I got a Graphics2D object from the bufferedImage of old image and called drawImage method of Graphics2D class. I then saved the old image to disk. When I open the saved image I find only the old image with white background changed to transparent. Can anyone suggest me what is error with my code or how can I get to fix my error ?
BufferedImage newImage = ImageIO.read(new File("new.png"));
BufferedImage oldImage = ImageIO.read(new File("old.png"));
newImage = makeWhiteTransparent(newImage);
oldImage = makeWhiteTransparent(oldImage);
Graphics2D graphics = (Graphics2D) oldImage.getGraphics();
graphics.drawImage(newImage,null, 0,0);
File outputImage = new File("merged.png");
ImageIO.write(oldImage, "png", outputImage);
My makeWhiteTransparent method goes like this:
public static BufferedImage makeWhiteTransparent(BufferedImage img){
BufferedImage dst = new BufferedImage(img.getWidth(), img.getHeight(), BufferedImage.TYPE_4BYTE_ABGR);
dst.getGraphics().drawImage(img, 0, 0, null);
int markerRGB = Color.WHITE.getRGB() | 0xFF000000;
int width = dst.getWidth();
int height = dst.getHeight();
for(int x = 0; x < width; x++){
for(int y = 0; y < height; y++){
int rgb = dst.getRGB(x, y);
if ( ( rgb | 0xFF000000 ) == markerRGB ) {
int value = 0x00FFFFFF & rgb;
dst.setRGB(x, y, value);
}
}
}
return dst;
}
I tried changing graphics.drawImage(newImage, null,0,0) to graphics.drawImage(newImage, 0,0, null) and also changing TYPE_4BYTE_ABGR to TYPE_INT_ARGB as suggested but it did nothing. The error still exists.

This needs to be changed:
graphics.drawImage(newImage,null, 0,0);
to
graphics.drawImage(newImage, 0,0, null);
you are using the wrong version of drawImage - check http://docs.oracle.com/javase/7/docs/api/java/awt/Graphics2D.html
--
Change also the type TYPE_4BYTE_ABGR to TYPE_INT_ARGB
--
Here's how it works for me:
public BufferedImage makeWhiteTransparent(BufferedImage img){
BufferedImage dst = new BufferedImage(img.getWidth(), img.getHeight(), BufferedImage.TYPE_INT_ARGB);
dst.getGraphics().drawImage(img, 0, 0, null);
int markerRGB = 0x00ffffff; // Color.WHITE.getRGB() | 0xFF000000;
int width = dst.getWidth();
int height = dst.getHeight();
for(int x = 0; x < width; x++){
for(int y = 0; y < height; y++){
int rgb = dst.getRGB(x, y)&0x00ffffff;
if ( rgb == markerRGB ) {
int value = 0x00FFFFFF & rgb;
dst.setRGB(x, y, value);
}
}
}
return dst;
}
bim = makeWhiteTransparent(bim);
bim2 = makeWhiteTransparent(bim2);
Graphics2D graphics = (Graphics2D) bim.getGraphics();
graphics.drawImage(bim2,0,0, null);
g2.drawImage(bim, w/2-wc/2, h/2-hc/2, null);

I got the answer to my question finally. All I had to do was create a new BufferedImage and draw two images over it. Below is the code that works as expected:
BufferedImage newImage = ImageIO.read(new File("new.png"));
BufferedImage oldImage = ImageIO.read(new File("old.png"));
oldImage = makeWhiteTransparent(oldImage);
newImage = makeWhiteTransparent(newImage);
int width = Math.max(newImage.getWidth(), oldImage.getWidth());
int height = Math.max(newImage.getHeight(), oldImage.getHeight());
BufferedImage combined = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
Graphics graphics = combined.getGraphics();
graphics.drawImage(oldImage, 0, 0, null);
graphics.drawImage(newImage, 0, 0, null);
File outputImage = new File("merged.png");
ImageIO.write(combined, "PNG", outputImage);

Related

concat image file not able to create

I try to join two images. But not able to create it.
I am not able to understand what is the problem in the below code.
It is not able to create the concat.jpg file.
BufferedImage image = ImageIO.read(mainFile);
BufferedImage image1 = ImageIO.read(fileToMerge);
int width = Math.max(image.getWidth() , image1.getWidth());
int height = Math.max(image.getHeight() , image1.getHeight());
log.info("width {}", width);
log.info("height {}", height);
BufferedImage concatImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
Graphics2D graphics2D = concatImage.createGraphics();
graphics2D.drawImage(image, 0, image.getHeight(), null);
graphics2D.drawImage(image1, 0 , image1.getHeight(), null);
ImageIO.write(concatImage, "jpg", new File(Constants.LOCAL_FOLDER + "/concat.jpg"));
You want the height of concatImage to be the combined height of image and image1.
You want to draw image at coordinates (0,0) and you want to draw image1 at x = 0 and y = height of image
Try the following.
BufferedImage image = ImageIO.read(mainFile);
BufferedImage image1 = ImageIO.read(fileToMerge);
int width = Math.max(image.getWidth() , image1.getWidth());
int height = image.getHeight() + image1.getHeight();
log.info("width {}", width);
log.info("height {}", height);
BufferedImage concatImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
Graphics2D graphics2D = concatImage.createGraphics();
graphics2D.drawImage(image, 0, 0, null);
graphics2D.drawImage(image1, 0, image.getHeight(), null);
ImageIO.write(concatImage, "jpg", new File(Constants.LOCAL_FOLDER + "/concat.jpg"));
Note that you should call graphics2D.dispose() when you no longer need to use it.

Way to change transparency with java swing.image

I draw graphics in frame with this methods.
public void paint(Graphics g) {
screenImage = createImage(1280, 720);
screenGraphic = screenImage.getGraphics();
screenDraw((Graphics2D) screenGraphic);
//g.drawImage(BG, 0, 0, null);
g.drawImage(screenImage, 0, 0, null);
}
public void screenDraw(Graphics2D g) {
g.drawImage(BG, 0, 0, null);
Graphics2D g2 = (Graphics2D)g;
if(isMainScreen) {
//g2.setComposite(alphaComposite);
g2.drawImage(selectedImage, 100, 220, null);
}
paintComponents(g);
this.repaint();
}
I want to have selectedImage to be transparency 50% or other integer.
private Image selectedImage = new ImageIcon(Main.class.getResource("../pic/something.jpg")).getImage();
this is selectedImage, and it works well.
Adapt a bit of Image -> BufferedImage code, and then you can set each pixel to be transparent
Image selectedImage = new ImageIcon([...]).getImage();
//Image -> BufferedImage code
BufferedImage img = new BufferedImage(selectedImage.getWidth(null), selectedImage.getHeight(null), BufferedImage.TYPE_INT_ARGB);
Graphics2D g = img.createGraphics();
g.drawImage(selectedImage, 0, 0, null);
g.dispose();
//set each pixel to be transparent
int transparency = 127; //0-255, 0 is invisible, 255 is opaque
int colorMask = 0x00FFFFFF; //AARRGGBB
int alphaShift = 24;
for(int y = 0; y < img.getHeight(); y++)
for(int x = 0; x < img.getWidth(); x++)
img.setRGB(x, y, (img.getRGB(x, y) & colorMask) | (transparency << alphaShift));
//img is now transparent, can replace selectedImage if you want (optional)
selectedImage = img;
If you use ImageIO.read(File) instead of ImageIcon.getImage(), it will give you a BufferedImage directly

Removing BufferedImage pixel values and or setting them transparent

I have been working with the polygon class and trying to set the pixel values inside of the polygon to transparent or remove them all together if this is possible, however I have hit a bit of a wall as I am trying to store the values as RGB int values and don't know how I would be able to make a pixel transparent/removed via this method.
Additionally to this I would also like to do the same thing but keeping pixels inside the polygon and deleting those outside if possible in order to be left with only the pixels contained within the polygon. I have searched around for this before but to no avail.
I did attempt to create a SSCCE for this to make it easier to work with and view for anyone taking the time to help however as its part of a much larger programme that I am working on creating one is proving to take some time, however once I have one working to better demonstrate this problem I will edit this post.
Thank you to anyone for taking the time to help me with this problem
Below I have some code for what I am currently using to segment the pixels that are contained within an already specified polygon. This is extremely similar to the way i do it for setting pixels outside the polygon to transparent only with the if statement arguments swapped around to remove a segment of the image and haveing a return for newImage rather than save image stuff and it works perfectly, however when I do it this way to save the pixels contained in the polygon it doesn't save for some reason.
public void saveSegment(int tabNum, BufferedImage img) {
segmentation = new GUI.Segmentation();
Polygon p = new Polygon();
Color pixel;
p = createPolygon(segmentation);
int height = img.getHeight();
int width = img.getWidth();
newImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
//loop through the image to fill the 2d array up with the segmented pixels
for(int y = 0; y < height; y++) {
for(int x = 0; x < width; x++) {
//If the pixel is inside polygon
if(p.contains(x, y) == true) {
pixel = new Color(img.getRGB(x, y));
//set pixel equal to the RGB value of the pixel being looked at
int r = pixel.getRed(); // red component 0...255
int g = pixel.getGreen(); // green component 0...255
int b = pixel.getBlue(); // blue component 0...255
int a = pixel.getAlpha(); // alpha (transparency) component 0...255
int col = (a << 24) | (r << 16) | (g << 8) | b;
newImage.setRGB(x, y, col);
}
else {
pixel = new Color(img.getRGB(x, y));
int a = 0; // alpha (transparency) component 0...255
int col = (a << 24);
newImage.setRGB(x, y, col);
}
}
}
try {
//then save as image once all in correct order
ImageIO.write(newImage, "bmp", new File("saved-Segment.bmp"));
JOptionPane.showMessageDialog(null, "New image saved successfully");
} catch (IOException e) {
e.printStackTrace();
}
}
An easier way is to use Java2D's clipping capability:
BufferedImage cutHole(BufferedImage image, Polygon holeShape) {
BufferedImage newImage = new BufferedImage(
image.getWidth(), image.getHeight(), image.getType());
Graphics2D g = newImage.createGraphics();
Rectangle entireImage =
new Rectangle(image.getWidth(), image.getHeight());
Area clip = new Area(entireImage);
clip.subtract(new Area(holeShape));
g.clip(clip);
g.drawImage(image, 0, 0, null);
g.dispose();
return newImage;
}
BufferedImage clipToPolygon(BufferedImage image, Polygon polygon) {
BufferedImage newImage = new BufferedImage(
image.getWidth(), image.getHeight(), image.getType());
Graphics2D g = newImage.createGraphics();
g.clip(polygon);
g.drawImage(image, 0, 0, null);
g.dispose();
return newImage;
}

How can I get my image to flip?

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;
}

resize jpeg image in java

i am working on image comparison in java. I think before going to compare the images, it is better to process the images for setting a fixed size image. Is there any java functionality to resize the images. I want to rescale the images to 300*225.
BufferedImage img = ImageIO.read(imageFile);
Image scaled = img.getScaledInstance(300, 255, Image.SCALE_DEFAULT);
You can also take a look at the java-image-scaling library.
public ImageIcon resizeImage(String filePath, int w, int h) {
String data = filePath;
BufferedImage bsrc, bdest;
ImageIcon theIcon;
//scale the image
try
{
bsrc = ImageIO.read(new File(data));
bdest = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
Graphics2D g = bdest.createGraphics();
AffineTransform at = AffineTransform.getScaleInstance((double) w / bsrc.getWidth(),
(double) h / bsrc.getHeight());
g.drawRenderedImage(bsrc, at);
//add the scaled image
theIcon = new ImageIcon(bdest);
return theIcon;
}
catch (Exception e)
{
System.out.println("This image can not be resized. Please check the path and type of file.");
return null;
}
}
BufferedImage createResizedCopy(Image originalImage,
int scaledWidth, int scaledHeight,
boolean preserveAlpha)
{
int imageType = preserveAlpha ? BufferedImage.TYPE_INT_RGB : BufferedImage.TYPE_INT_ARGB;
BufferedImage scaledBI = new BufferedImage(scaledWidth, scaledHeight, imageType);
Graphics2D g = scaledBI.createGraphics();
if (preserveAlpha) {
g.setComposite(AlphaComposite.Src);
}
g.drawImage(originalImage, 0, 0, scaledWidth, scaledHeight, null);
g.dispose();
return scaledBI;
}
This threads answers your question well
Very interesting article on manipulating images

Categories