How to draw on buffered image with java graphics? - java

My issue: Every time I create graphics from a buffered image and then draw another buffered image to the graphics I get an image that is blank.
My code is as follows.
Graphics2D g2d = atlas.createGraphics();
// images[i] is a buffered image read the fileio
g2d.drawImage(images[i], null, x, y); // Image is not blank, been tested
g2d.dispose();
// then save image
Ironically after trying to create a self contained example which is as follows... it worked. I am not quite sure what I am doing wrong in my code and I am wondering if it is because maybe an image is not static, could an image or another variable not being static affect my drawing?
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import javax.imageio.ImageIO;
public class Main {
public static void main(String[] args) {
String FOLDER_LOCATION = "./Images/";
BufferedImage atlas = new BufferedImage(2048, 2048, BufferedImage.TYPE_INT_ARGB);
BufferedImage redSquare = readImage(FOLDER_LOCATION + "red.png");
Graphics2D g2d = atlas.createGraphics();
g2d.drawImage(redSquare, null, 0, 0);
g2d.dispose();
writeImage(atlas, FOLDER_LOCATION + "atlas.png");
}
public static BufferedImage readImage(String location) {
BufferedImage img = null;
InputStream is = null;
try {
is = new FileInputStream(location);
img = ImageIO.read(is);
} catch(Exception e) {
e.printStackTrace();
} finally {
try {
is.close();
} catch(Exception e) {
e.printStackTrace();
}
}
return img;
}
public static void writeImage(BufferedImage bi, String location) {
try {
File file = new File(location);
ImageIO.write(bi, "png", file);
} catch(Exception e) {
e.printStackTrace();
}
}
}
After I save the image I see just a blank 2048 by 2048 image. I printed the entire image out and I get (0, 0, 0), but if I print out any of the image I am drawing to the atlas I get something like (72, 32, 283).
I am not quite sure what I am doing wrong, but my entire source code for this project is here: https://github.com/gemurdock/jTextureAtlas and the branch I am working on is here: https://github.com/gemurdock/jTextureAtlas/tree/alpha.
You have to look at the alpha branch to see my code

Related

java croped image all black

I am trying to crop an image using a java, here is my code:
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
public class crop
{
public static void main(String[] args)
{
BufferedImage img = null;
try
{
img = ImageIO.read(new File("/Users/mathewlewis/desktop/pic.jpg"));
String width = "" + img.getWidth();
String height = "" + img.getHeight();
cout("heigth = " + height + " and width = " + width);
BufferedImage crp = img.getSubimage(0,0,100,200);
try {
File outputfile = new File("crop_pic.jpg");
ImageIO.write(crp, "jpg", outputfile);
}
catch (IOException e)
{
System.out.println("error");
}
}
catch (IOException e)
{
System.out.println("error");
}
}
}
Everything runs fine (no errors), but when I open crop_pic.jpg it is all black. Here is pic.jpg.
I would like to know why the image comes out all black, and how I can fix it.
I tried this
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
public class crop
{
public static void main(String[] args)
{
BufferedImage img = null;
try
{
img = ImageIO.read(new File("/Users/mathewlewis/desktop/pic.jpg"));
BufferedImage rgbImage = new BufferedImage(img.getWidth(), img.getHeight(), BufferedImage.TYPE_3BYTE_BGR);
ColorConvertOp op = new ColorConvertOp(null);
op.filter(img, rgbImage);
BufferedImage crp = rgbImage.getSubimage(300,300,rgbImage.getWidth()-300,rgbImage.getHeight()-300);
try {
File outputfile = new File("crop_pic.jpg");
ImageIO.write(crp, "jpg", outputfile);
}
catch (IOException e)
{
System.out.println("error");
}
}
catch (IOException e)
{
System.out.println("error");
}
}
}
and got this error:
crop.java:16: error: cannot find symbol
ColorConvertOp op = new ColorConvertOp(null);
^
symbol: class ColorConvertOp
location: class crop
crop.java:16: error: cannot find symbol
ColorConvertOp op = new ColorConvertOp(null);
^
symbol: class ColorConvertOp
location: class crop
2 errors
Thank you Forseth11!! should have noticed that I didn't import java.awt.image.ColorConvertOp! You've been a great help. Thanks a lot!!!
I looked around a bit and found that other people have had a similar problem. On my end when testing this I got a strangely colored image, not a black image. This problem is caused because ImageIO is reading the image wrong.
Here is what I have come up with which works, but since I could not replicate your problem and get a black image this may not work for you.
img = ImageIO.read(new File("/Users/mathewlewis/desktop/pic.jpg"));
BufferedImage rgbImage = new BufferedImage(img.getWidth(), img.getHeight(),
BufferedImage.TYPE_3BYTE_BGR);
ColorConvertOp op = new ColorConvertOp(null);
op.filter(img, rgbImage);
String width = "" + rgbImage.getWidth();
String height = "" + rgbImage.getHeight();
System.out.println("heigth = " + height + " and width = " + width);
BufferedImage crp = rgbImage.getSubimage(300,300,rgbImage.getWidth()-300,rgbImage.getHeight()-300);
These are some other posts which have a similar issue:
jpeg image color gets drastically changed after just ImageIO.read() and ImageIO.write()
Unable to read JPEG image using ImageIO.read(File file)
Edit: I changed where it cropped, so it is easy to see because the upper left part of the image is mostly yellow.

Take picture using webcam in netbeans java?

I have been busy with trying to get the webcam to work within netbeans over the past few days.
The problem I am having is to get the coding to activate and take a picture using the webcam.
So far I have seen that I will have to use the OpenCV and some other JAR files.
Please could someone help me out by perfecting the coding I have below:
private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) {
// coding for webcam and taking a picture
OpenCVFrameGrabber grabber = new OpenCVFrameGrabber(0);
try
{
//start of the webcam for taking the picture
grabber.start();
Image IM = this.takePicture();
//stops the webcam
grabber.stop();
}
catch (Exception e)
{
//displays error message if problem with webcam
JOptionPane.showMessageDialog(null, "Problem accessing or using the Webcam!");
}
}
What I need is for the picture to be displayed in a label on my interface after it has taken the picture.
The Open CV has been successfully installed and now just the coding needed to get the picture taken.
Any Help would be helpful.
Okay, your coding is a bit off, it does need some changes made to it. You are on the right track however.
I do have a sample code that may be able to help you out which works:
private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) {
// TODO add your handling code here:
// coding for webcam and taking a picture
OpenCVFrameGrabber grabber = new OpenCVFrameGrabber(0);
try
{
//start of the webcam for taking the picture
grabber.start();
//grabs teh image taken from the webcam
IplImage img = grabber.grab();
//checks if the webcam has taken the picture and if the picture if mot empty
if(img != null)
{
//determines where to save the picture
cvSaveImage("C:\\User1\\PrifilePicture\\"+lbl_StudnetLogin.getText()+".jpeg", img);
}
//stops the webcam
grabber.stop();
//used to resize teh picture taken in order to display picture to the user
Image imeResize = ImageIO.read(new File("C:\\SalVentri\\PrifilePicture\\"+lbl_StudnetLogin.getText()+".jpeg"));
//1st ---> width _______2sn ---> height
lbl_Profile.setIcon(new ImageIcon(imeResize.getScaledInstance(155, 100, 100)));
}
catch (Exception e)
{
//displays error message if problem with webcam
JOptionPane.showMessageDialog(null, "Problem accessing or using the Webcam!");
}
}
Hope this helps
I found that this works as well.
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.image.BufferedImage;
import java.awt.image.DataBufferByte;
import java.awt.image.WritableRaster;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.InputStream;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;
import org.opencv.core.*;
import org.opencv.highgui.Highgui;
import org.opencv.highgui.VideoCapture;
public class JPanelOpenCV extends JPanel{
BufferedImage image;
public static void main (String args[]) throws InterruptedException{
System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
JPanelOpenCV t = new JPanelOpenCV();
VideoCapture camera = new VideoCapture(0);
Mat frame = new Mat();
camera.read(frame);
if(!camera.isOpened()){
System.out.println("Error");
}
else {
while(true){
if (camera.read(frame)){
BufferedImage image = t.MatToBufferedImage(frame);
t.window(image, "Original Image", 0, 0);
t.window(t.grayscale(image), "Processed Image", 40, 60);
//t.window(t.loadImage("ImageName"), "Image loaded", 0, 0);
break;
}
}
}
camera.release();
}
#Override
public void paint(Graphics g) {
g.drawImage(image, 0, 0, this);
}
public JPanelOpenCV() {
}
public JPanelOpenCV(BufferedImage img) {
image = img;
}
//Show image on window
public void window(BufferedImage img, String text, int x, int y) {
JFrame frame0 = new JFrame();
frame0.getContentPane().add(new JPanelOpenCV(img));
frame0.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame0.setTitle(text);
frame0.setSize(img.getWidth(), img.getHeight() + 30);
frame0.setLocation(x, y);
frame0.setVisible(true);
}
//Load an image
public BufferedImage loadImage(String file) {
BufferedImage img;
try {
File input = new File(file);
img = ImageIO.read(input);
return img;
} catch (Exception e) {
System.out.println("erro");
}
return null;
}
//Save an image
public void saveImage(BufferedImage img) {
try {
File outputfile = new File("Images/new.png");
ImageIO.write(img, "png", outputfile);
} catch (Exception e) {
System.out.println("error");
}
}
//Grayscale filter
public BufferedImage grayscale(BufferedImage img) {
for (int i = 0; i < img.getHeight(); i++) {
for (int j = 0; j < img.getWidth(); j++) {
Color c = new Color(img.getRGB(j, i));
int red = (int) (c.getRed() * 0.299);
int green = (int) (c.getGreen() * 0.587);
int blue = (int) (c.getBlue() * 0.114);
Color newColor =
new Color(
red + green + blue,
red + green + blue,
red + green + blue);
img.setRGB(j, i, newColor.getRGB());
}
}
return img;
}
public BufferedImage MatToBufferedImage(Mat frame) {
//Mat() to BufferedImage
int type = 0;
if (frame.channels() == 1) {
type = BufferedImage.TYPE_BYTE_GRAY;
} else if (frame.channels() == 3) {
type = BufferedImage.TYPE_3BYTE_BGR;
}
BufferedImage image = new BufferedImage(frame.width(), frame.height(), type);
WritableRaster raster = image.getRaster();
DataBufferByte dataBuffer = (DataBufferByte) raster.getDataBuffer();
byte[] data = dataBuffer.getData();
frame.get(0, 0, data);
return image;
}
}

How can to scale svg images automatically in javafx 8?

I have drawn an image in inkscape.I can see the option to export it as javafx script file i.e .fx. But as per my knowledge .fx is obsolete now in javafx 8.So it is not recommend to use it.I can use the svg images using the batik where I have to convert them to javafx image format then I can set it to imageview .I want this image to be scaled automatically when ever i moved my application to bigger resolution.Any help on this will be appreciated .
My custom Transcoder Code
import java.awt.image.BufferedImage;
import java.io.InputStream;
import javafx.embed.swing.SwingFXUtils;
import javafx.scene.image.Image;
import javafx.scene.image.WritableImage;
import org.apache.batik.transcoder.TranscoderException;
import org.apache.batik.transcoder.TranscoderInput;
import org.apache.batik.transcoder.TranscoderOutput;
import org.apache.batik.transcoder.image.ImageTranscoder;
import org.apache.batik.transcoder.image.PNGTranscoder;
class MyTranscoder extends ImageTranscoder {
private BufferedImage image = null;
private InputStream url;
MyTranscoder(InputStream url) {
this.url = url;
}
#Override
public BufferedImage createImage(int w, int h) {
image = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
return image;
}
#Override
public void writeImage(BufferedImage img, TranscoderOutput out) {
}
public BufferedImage getImage() {
return image;
}
public Image getJavafxCompatibleImage(int width, int height) {
this.addTranscodingHint(PNGTranscoder.KEY_WIDTH, (float) width);
this.addTranscodingHint(PNGTranscoder.KEY_HEIGHT, (float) height);
TranscoderInput input = new TranscoderInput(url);
try {
this.transcode(input, null);
} catch (TranscoderException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
BufferedImage bimage = this.getImage();
WritableImage wimage = SwingFXUtils.toFXImage(bimage, null);
return wimage;
}
}

How to make image from BufferImage

I am trying to make image from BufferImage, but it's not working. here is my code ...
This code is not working, can anyone please help me ...
try {
BufferedImage bimage = (BufferedImage)(new ImageIcon("str")).getImage();
BufferedImage image = new BufferedImage(500, 500, bimage.TYPE_BYTE_GRAY);
File outputfile = new File("saved.png");
ImageIO.write(image, "png", outputfile);
Image image_1 = ImageIO.read(new File("saved.png"));
lp2_2.setIcon(new ImageIcon(image_1));
} catch (IOException e) {}
Maybe your way of converting IconImage to BufferedImageis not right.
So you can try the following snippet
BufferedImage bi = new BufferedImage(icon.getIconWidth(),icon.getIconHeight(), BufferedImage.TYPE_INT_RGB);
Graphics g = bi.createGraphics();
// paint the Icon to the BufferedImage.
icon.paintIcon(null, g, 0,0);
g.dispose();
After this you can use BufferdImage as you are already using.
Or you can look this question Java converting Image to BufferedImage
if you want to see how to convert Image to 'BifferedImage' because as given in this post you can't just cast Image to BufferedImage.
Although i would request you to add more information like what error or exception you are getting and may be if there is an exception add the stacktrace .
Hopefully this will work better, I have tried it many times.
public void writeImage(String output, String fileName, BufferedImage img) throws IOException {
File file = new File(output + "\\HE\\" + fileName + ".bmp");
ImageIO.write(img, "bmp", file);
}
=================================================================================
If you want to use this image in any JPanel then here is code for it, it is already working fine,
import java.awt.BorderLayout;
import java.awt.image.BufferedImage;
import java.io.File;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.SwingUtilities;
import javax.swing.WindowConstants;
public class ShowImage {
public ShowImage(final String filename) throws Exception {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
JFrame editorFrame = new JFrame("My Frame " +filename);
editorFrame.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
BufferedImage image = null;
try {
image = ImageIO.read(new File(filename));
} catch (Exception e) {
e.printStackTrace();
System.exit(1);
}
ImageIcon imageIcon = new ImageIcon(image);
JLabel jLabel = new JLabel();
jLabel.setIcon(imageIcon);
editorFrame.getContentPane().add(jLabel, BorderLayout.CENTER);
editorFrame.pack();
editorFrame.setLocationRelativeTo(null);
editorFrame.setVisible(true);
}
});
}
}
here is my new code and its working properly ... thank you all for your kind support ...
try{
BufferedImage cat = ImageIO.read(new File(str));
for (int w = 0; w < cat.getWidth(); w++) {
for (int h = 0; h < cat.getHeight(); h++) {
Color color = new Color(cat.getRGB(w, h));
//int averageColor = ((color.getRed() + color.getGreen() + color.getBlue()) / 3);
//int averageColor = int((color.getRed())*0.21 +(color.getGreen())*0.71+(color.getBlue())*0.07);
double r =color.getRed()*0.21;
double g =color.getGreen()*0.71;
double b =color.getBlue()*0.07;
int averageColor = (int)(r+g+b);
Color avg = new Color(averageColor, averageColor, averageColor);
cat.setRGB(w, h, avg.getRGB());
}
}
ImageIO.write(cat, "jpg", new File("image_greyscale.jpg"));
lp2_2.setIcon(new ImageIcon((new ImageIcon("image_greyscale.jpg")).getImage().getScaledInstance( 600, 600, java.awt.Image.SCALE_SMOOTH )));
}catch(IOException e){
e.printStackTrace();
System.exit(1);}
Everyone here missed the point. A BufferedImage is an Image.

Drawing Filled Rectangle over a BufferedImage

So I am attempting to create an application that can black-out sections of a survey that contains sensitive information. However I've run into a bit of a problem.
What I want to do is draw filled black rectangles over a BufferedImage given x, y, width, and height of desired region to black out, then write that new image back to my filesystem. Here's my code.
File imageFile = new File("images/template.jpg");
BufferedImage img = ImageIO.read(imageFile);
Graphics2D graph = img.createGraphics();
graph.setColor(Color.BLACK);
graph.fill(new Rectangle(x, y, width, height));
graph.dispose();
ImageIO.write(img, "jpg", new File("images/template.jpg"));
For whatever reason the image in the resource doesn't change after this code segment. Any ideas on what I'm doing wrong?
I created a runnable example of your code, and it worked fine for me. I ran this code using Java 8.
Here's the altered image. I drew the black square on an image I had.
And here's the code I ran. I read the original image directly from my file system.
package com.ggl.testing;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
public class ImageProcessing implements Runnable {
public static void main(String[] args) {
new ImageProcessing().run();
}
#Override
public void run() {
File imageFile = new File("C:\\Users\\Owner\\Pictures\\Saved Pictures\\Analog Clock Calendar.jpg");
BufferedImage img;
try {
img = ImageIO.read(imageFile);
} catch (IOException e1) {
e1.printStackTrace();
return;
}
Graphics2D graph = img.createGraphics();
graph.setColor(Color.BLACK);
graph.fill(new Rectangle(100, 100, 100, 100));
graph.dispose();
try {
ImageIO.write(img, "jpg",
new File("altered.jpg"));
} catch (IOException e) {
e.printStackTrace();
}
}
}
My conclusion is that you either didn't read the image correctly, your x, y, width, and/or height were outside the limits of the image, or something else that I'm missing.
I know is an old question, but maybe it can be useful to someone,
I think you shoud use this
graph.drawImage(x,y,width,height); //First you draw the image
graph.setColor(Color.black); //Then set the color to black
graph.fillRect(img.getX(), img.getY(), img.getWidth(), img.getHeight());// Finally draw a black rectangle on it
By the way is hard to find a solution without a little more code.
Hope it will be usefull.
Very late to this answer but you are saving the image and not the graph you are creating. I think it must be a BufferedImage again to save
You have just to replace this line:
Graphics2D graph = img.createGraphics();
with this:
Graphics2D graph = img.getGraphics();

Categories

Resources