I am trying to transform an image by flipping it horizontally and resizing it. The problem is that when the transformation is done the picture's colors are all weird, it has gotten this reddish tone. Is it possible to fix this somehow, I think I read somewhere that it might be some bug in the AWT library but I am not sure?
Here is the code:
import java.awt.Graphics2D;
import java.awt.geom.AffineTransform;
import java.awt.image.AffineTransformOp;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
public class LocalImageSizeFlip {
public static void main(String[] args) {
BufferedImage img = null;
try {
img = ImageIO.read(new File("C:\\picture.jpg"));
AffineTransform tx = AffineTransform.getScaleInstance(1, -1);
tx.translate(0, -img.getHeight(null));
AffineTransformOp op = new AffineTransformOp(tx, AffineTransformOp.TYPE_NEAREST_NEIGHBOR);
img = op.filter(img, null);
img = resize(img, 100, 75);
File newFile = new File("newPicture.jpg");
ImageIO.write(img, "JPEG", newFile);
} catch (IOException e) {
e.printStackTrace();
}
}
private static BufferedImage resize(BufferedImage image, int width, int height) {
BufferedImage resizedImage = new BufferedImage(width, height,
BufferedImage.TYPE_INT_ARGB);
Graphics2D g = resizedImage.createGraphics();
g.drawImage(image, 0, 0, width, height, null);
g.dispose();
return resizedImage;
}
}
Having an image develop a tint usually means the image is being rendered using the wrong colorspace, Adobe RGB vs. sRGB being a perennial favorite. Try changing TYPE_INT_ARGB to TYPE_INT_RGB in your code.
You can also try the following type: BufferedImage.TYPE_3BYTE_BGR
If you have any images already converted and those are almost pinkish/reddish.
You can convert those into RGB again.
try {
File folder = new File("photo/old");
File[] list = folder.listFiles();
for (File f : list) {
String url = f.getAbsolutePath();
String replce1 = url.replace('\\', '/');
File file = new File(replce1);
if (file.exists()) {
FileInputStream fis = new FileInputStream(file);
byte[] buff = new byte[fis.available()];
fis.read(buff);
BufferedImage bi = ImageIO.read(file);
BufferedImage biOriginal = new BufferedImage(1200, 800,
BufferedImage.TYPE_INT_RGB);
Graphics2D g = resizedImage.createGraphics();
g.drawImage(bi, 0, 0, 1200, 800, null);
g.dispose();
fis.close();
FileOutputStream fos2 = new FileOutputStream("photo/new/"+file.getName());
ByteArrayOutputStream baos2 = new ByteArrayOutputStream();
ImageIO.write(biOriginal, Main.extensionWithotDot, baos2);
baos2.flush();
byte[] imageInByte2 = baos2.toByteArray();
fos2.write(imageInByte2);
fos2.close();
}
}
} catch (Exception e) {
e.printStackTrace();
}
i would like to know on how to save a image that user selected previously. I only know how to allow user to select image.
This is my current code I have.
private void jButton3ActionPerformed(java.awt.event.ActionEvent evt) {
JFileChooser chooser = new JFileChooser();
chooser.showOpenDialog(null);
File f = chooser.getSelectedFile();
// String filename = f.getAbsolutePath();
//jTextField1.setText(filename);
try {
ImageIcon ii=new ImageIcon(scaleImage(120, 120, ImageIO.read(new File(f.getAbsolutePath()))));//get the image from file chooser and scale it to match JLabel size
jLabel3.setIcon(ii);
} catch (Exception ex) {
ex.printStackTrace();
}
}
public static BufferedImage scaleImage(int w, int h, BufferedImage img) throws Exception {
BufferedImage bi;
bi = new BufferedImage(w, h, BufferedImage.TRANSLUCENT);
Graphics2D g2d = (Graphics2D) bi.createGraphics();
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2d.addRenderingHints(new RenderingHints(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY));
g2d.drawImage(img, 0, 0, w, h, null);
g2d.dispose();
return bi;
}
Try this code :
BufferedImage img = ...;
String location = ...;
String format = ...; // "PNG" for example
ImageIO.write(img, format, new File(location));
I am trying to transform an image by flipping it horizontally and resizing it. The problem is that when the transformation is done the picture's colors are all weird, it has gotten this reddish tone. Is it possible to fix this somehow, I think I read somewhere that it might be some bug in the AWT library but I am not sure?
Here is the code:
import java.awt.Graphics2D;
import java.awt.geom.AffineTransform;
import java.awt.image.AffineTransformOp;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
public class LocalImageSizeFlip {
public static void main(String[] args) {
BufferedImage img = null;
try {
img = ImageIO.read(new File("C:\\picture.jpg"));
AffineTransform tx = AffineTransform.getScaleInstance(1, -1);
tx.translate(0, -img.getHeight(null));
AffineTransformOp op = new AffineTransformOp(tx, AffineTransformOp.TYPE_NEAREST_NEIGHBOR);
img = op.filter(img, null);
img = resize(img, 100, 75);
File newFile = new File("newPicture.jpg");
ImageIO.write(img, "JPEG", newFile);
} catch (IOException e) {
e.printStackTrace();
}
}
private static BufferedImage resize(BufferedImage image, int width, int height) {
BufferedImage resizedImage = new BufferedImage(width, height,
BufferedImage.TYPE_INT_ARGB);
Graphics2D g = resizedImage.createGraphics();
g.drawImage(image, 0, 0, width, height, null);
g.dispose();
return resizedImage;
}
}
Having an image develop a tint usually means the image is being rendered using the wrong colorspace, Adobe RGB vs. sRGB being a perennial favorite. Try changing TYPE_INT_ARGB to TYPE_INT_RGB in your code.
You can also try the following type: BufferedImage.TYPE_3BYTE_BGR
If you have any images already converted and those are almost pinkish/reddish.
You can convert those into RGB again.
try {
File folder = new File("photo/old");
File[] list = folder.listFiles();
for (File f : list) {
String url = f.getAbsolutePath();
String replce1 = url.replace('\\', '/');
File file = new File(replce1);
if (file.exists()) {
FileInputStream fis = new FileInputStream(file);
byte[] buff = new byte[fis.available()];
fis.read(buff);
BufferedImage bi = ImageIO.read(file);
BufferedImage biOriginal = new BufferedImage(1200, 800,
BufferedImage.TYPE_INT_RGB);
Graphics2D g = resizedImage.createGraphics();
g.drawImage(bi, 0, 0, 1200, 800, null);
g.dispose();
fis.close();
FileOutputStream fos2 = new FileOutputStream("photo/new/"+file.getName());
ByteArrayOutputStream baos2 = new ByteArrayOutputStream();
ImageIO.write(biOriginal, Main.extensionWithotDot, baos2);
baos2.flush();
byte[] imageInByte2 = baos2.toByteArray();
fos2.write(imageInByte2);
fos2.close();
}
}
} catch (Exception e) {
e.printStackTrace();
}
So I am trying to make a small game for a project in college. I have an image class that loads the images etc. I know this class works because I tested it all when I made it. But then I decided to use a form maker, in this case WindowsBuilder Pro to make a form that was better then I could code. I am now trying to call a function that in theory will load call the images class and load the image then add that image as an imageicon to a label within a jPanel. But I am getting nothing. Any help?
private void loadres(){
String PROGRAM_DIRECTORY = "E:/WordGame/bin/Images/";
Functions.Resources rs = new Functions.Resources();
rs.loadResources();
Functions.ImageLib iL = rs.getIL();
try {
BGImage = new JLabel(new ImageIcon(iL.mergeImages(iL.getImageArray(0),iL.getImage(PROGRAM_DIRECTORY + "Astroid1Image.png"))));
} catch (IOException e) {
e.printStackTrace();
}
BGImage.revalidate();
BGImage.repaint();
}
And here is the Image functions I am using:
public class ImageLib {
private ArrayList<BufferedImage> BIArray = new ArrayList<BufferedImage>();
public ImageLib(){
}
public BufferedImage getImage(String ref){
BufferedImage Bi = null;
try{
Bi = ImageIO.read(new File(ref));
}catch (Exception e) {
e.printStackTrace();
}
return Bi;
}
public BufferedImage resizeImage(BufferedImage Bi, int nW, int nH){
int w = Bi.getWidth();
int h = Bi.getHeight();
BufferedImage nBi = new BufferedImage(nW, nH, Bi.getType());
Graphics2D g = nBi.createGraphics();
g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
g.drawImage(Bi,0,0,nW,nH,0,0,w,h,null);
g.dispose();
return nBi;
}
public void addToArray(BufferedImage img){
BIArray.add(img);
}
public BufferedImage getImageArray(int index){
return (BufferedImage) BIArray.get(index);
}
public BufferedImage mergeImages(BufferedImage I1, BufferedImage I2) throws IOException{
int w = Math.max(I1.getWidth(), I2.getWidth());
int h = Math.max(I1.getHeight(), I2.getHeight());
BufferedImage combined = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
Graphics g = combined.getGraphics();
g.drawImage(I1, 0, 0, null);
g.drawImage(I2, 0, 0, null);
g.dispose();
return combined;
}
}
Here is my answer ^^
ClassLoader cldr = this.getClass().getClassLoader();
java.net.URL imageURL = cldr.getResource("path/to/your/images/picture.gif");
ImageIcon imgIcon = new ImageIcon(imageURL);
I know how to capture a screenshot by using Robot, Windowtester or FEST. I also know how to read a pixel from the screen by using robot.
int x = 10;
int y = 10;
Color px = getPixelColor(int x, int y);
However, I don't know how to read a pixel from an image that is already captured. I'm planning to compare a current image, with an image from file. Lets say both are PNG. Are there any frameworks that I can use to compare images pixel by pixel?
Is this in Java? If so, you can use ImageIO.read( "yourImage.png" ) to get a BufferedImage. That will have a getData() method which will give you a Raster object, on which you can call getPixel. See link
This should work:
javax.imageio.ImageIO.read(new File("filename.png"))
Then you can walk through the pixels and compare with the images pixel by pixel with this:
java.awt.image.BufferedImage.getRGB(int x, int y).
You can read image file: Reading/Loading an Image.
And then get color using getRGB method.
Load them as BufferedImage instances and it is relatively easy.
Here is part of code that creates images with text, then creates a new image that shows the difference between the image with & without text.
for (int xx=0; xx<width; xx++) {
for (int yy=0; yy<height; yy++) {
Color originalColor = new Color(originalImage.getRGB(xx,yy));
int r1 = originalColor.getRed();
int g1 = originalColor.getGreen();
int b1 = originalColor.getBlue();
Color newColor = new Color(textImage.getRGB(xx,yy));
int r2 = newColor.getRed();
int g2 = newColor.getGreen();
int b2 = newColor.getBlue();
Color bnw = Color.black;
if (r1==r2 && g1==g2 && b1==b2) {
bnw = Color.white;
}
bnwImage.setRGB(xx, yy, bnw.getRGB());
int rD = Math.abs(r1-r2);
int gD = Math.abs(g1-g2);
int bD = Math.abs(b1-b2);
Color differenceColor = new Color(rD,gD,bD);
differenceImage.setRGB(xx, yy, differenceColor.getRGB());
}
}
Screensot
Full code
import java.awt.image.BufferedImage;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.imageio.*;
import java.io.*;
import javax.imageio.stream.ImageOutputStream;
import javax.imageio.plugins.jpeg.JPEGImageWriteParam;
import java.util.Locale;
class ImageWriteTest {
private BufferedImage originalImage;
private BufferedImage textImage;
private BufferedImage differenceImage;
private BufferedImage bnwImage;
private JPanel gui;
private JCheckBox antialiasing;
private JCheckBox rendering;
private JCheckBox fractionalMetrics;
private JCheckBox strokeControl;
private JCheckBox colorRendering;
private JCheckBox dithering;
private JComboBox textAntialiasing;
private JComboBox textLcdContrast;
private JLabel label0_1;
private JLabel label0_4;
private JLabel label0_7;
private JLabel label1_0;
private JTextArea output;
final static Object[] VALUES_TEXT_ANTIALIASING = {
RenderingHints.VALUE_TEXT_ANTIALIAS_OFF,
RenderingHints.VALUE_TEXT_ANTIALIAS_ON,
RenderingHints.VALUE_TEXT_ANTIALIAS_GASP,
RenderingHints.VALUE_TEXT_ANTIALIAS_LCD_HBGR,
RenderingHints.VALUE_TEXT_ANTIALIAS_LCD_HRGB,
RenderingHints.VALUE_TEXT_ANTIALIAS_LCD_VBGR,
RenderingHints.VALUE_TEXT_ANTIALIAS_LCD_VRGB
};
final static Object[] VALUES_TEXT_LCD_CONTRAST = {
new Integer(100),
new Integer(150),
new Integer(200),
new Integer(250)
};
ImageWriteTest() {
int width = 280;
int height = 100;
gui = new JPanel(new BorderLayout(0,4));
originalImage = new BufferedImage(width,height,BufferedImage.TYPE_INT_RGB);
textImage = new BufferedImage(width,height,BufferedImage.TYPE_INT_RGB);
differenceImage = new BufferedImage(width,height,BufferedImage.TYPE_INT_RGB);
bnwImage = new BufferedImage(width,height,BufferedImage.TYPE_INT_RGB);
JPanel controls = new JPanel(new GridLayout(0,2,0,0));
antialiasing = new JCheckBox("Anti-aliasing", false);
rendering = new JCheckBox("Rendering - Quality", true);
fractionalMetrics = new JCheckBox("Fractional Metrics", true);
strokeControl = new JCheckBox("Stroke Control - Pure", false);
colorRendering = new JCheckBox("Color Rendering - Quality", true);
dithering = new JCheckBox("Dithering", false);
controls.add(antialiasing);
controls.add(rendering);
controls.add(fractionalMetrics);
controls.add(colorRendering);
textLcdContrast = new JComboBox(VALUES_TEXT_LCD_CONTRAST);
JPanel lcdContrastPanel = new JPanel(new FlowLayout(FlowLayout.LEADING));
lcdContrastPanel.add(textLcdContrast);
lcdContrastPanel.add(new JLabel("Text LCD Contrast"));
controls.add(lcdContrastPanel);
controls.add(strokeControl);
textAntialiasing = new JComboBox(VALUES_TEXT_ANTIALIASING);
controls.add(textAntialiasing);
controls.add(dithering);
ItemListener itemListener = new ItemListener(){
public void itemStateChanged(ItemEvent e) {
updateImages();
}
};
antialiasing.addItemListener(itemListener);
rendering.addItemListener(itemListener);
fractionalMetrics.addItemListener(itemListener);
strokeControl.addItemListener(itemListener);
colorRendering.addItemListener(itemListener);
dithering.addItemListener(itemListener);
textAntialiasing.addItemListener(itemListener);
textLcdContrast.addItemListener(itemListener);
Graphics2D g2d = originalImage.createGraphics();
GradientPaint gp = new GradientPaint(
0f, 0f, Color.red,
(float)width, (float)height, Color.orange);
g2d.setPaint(gp);
g2d.fillRect(0,0, width, height);
g2d.setColor(Color.blue);
for (int ii=0; ii<width; ii+=10) {
g2d.drawLine(ii, 0, ii, height);
}
g2d.setColor(Color.green);
for (int jj=0; jj<height; jj+=10) {
g2d.drawLine(0, jj, width, jj);
}
updateImages();
gui.add(controls, BorderLayout.NORTH);
JPanel images = new JPanel(new GridLayout(0,2,0,0));
images.add(new JLabel(new ImageIcon(originalImage)));
images.add(new JLabel(new ImageIcon(textImage)));
images.add(new JLabel(new ImageIcon(differenceImage)));
images.add(new JLabel(new ImageIcon(bnwImage)));
try {
label0_1 = new JLabel(new ImageIcon(getJpegCompressedImage(0.1f, textImage)));
images.add(label0_1);
label0_4 = new JLabel(new ImageIcon(getJpegCompressedImage(0.4f, textImage)));
images.add(label0_4);
label0_7 = new JLabel(new ImageIcon(getJpegCompressedImage(0.7f, textImage)));
images.add(label0_7);
label1_0 = new JLabel(new ImageIcon(getJpegCompressedImage(1.0f, textImage)));
images.add(label1_0);
} catch(IOException ioe) {
}
gui.add(images, BorderLayout.CENTER);
StringBuilder sb = new StringBuilder();
String[] names = {
"java.vendor",
"java.version",
"java.vm.version",
"os.name",
"os.version"
};
for (String name : names) {
addProperty(sb, name);
}
output = new JTextArea(sb.toString(),6,40);
gui.add(new JScrollPane(output), BorderLayout.SOUTH);
JOptionPane.showMessageDialog(null, gui);
}
private static void addProperty(StringBuilder builder, String name) {
builder.append( name + " \t" + System.getProperty(name) + "\n" );
}
/** Adapted from SO post by x4u. */
private Image getJpegCompressedImage(float quality, BufferedImage image) throws IOException {
ByteArrayOutputStream outStream = new ByteArrayOutputStream();
ImageWriter imgWriter = ImageIO.getImageWritersByFormatName( "jpg" ).next();
ImageOutputStream ioStream = ImageIO.createImageOutputStream( outStream );
imgWriter.setOutput( ioStream );
JPEGImageWriteParam jpegParams = new JPEGImageWriteParam( Locale.getDefault() );
jpegParams.setCompressionMode( ImageWriteParam.MODE_EXPLICIT );
jpegParams.setCompressionQuality( quality );
imgWriter.write( null, new IIOImage( image, null, null ), jpegParams );
ioStream.flush();
ioStream.close();
imgWriter.dispose();
BufferedImage compressedImage = ImageIO.read(new ByteArrayInputStream(outStream.toByteArray()));
JLabel label = new JLabel("Quality: " + quality);
label.setBackground(new Color(255,255,255,192));
label.setOpaque(true);
label.setSize(label.getPreferredSize());
label.paint(compressedImage.getGraphics());
return compressedImage;
}
private void updateImages() {
int width = originalImage.getWidth();
int height = originalImage.getHeight();
Graphics2D g2dText = textImage.createGraphics();
if (antialiasing.isSelected()) {
g2dText.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
} else {
g2dText.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_OFF);
}
if (rendering.isSelected()) {
g2dText.setRenderingHint(RenderingHints.KEY_RENDERING,
RenderingHints.VALUE_RENDER_QUALITY);
} else {
g2dText.setRenderingHint(RenderingHints.KEY_RENDERING,
RenderingHints.VALUE_RENDER_SPEED);
}
if (fractionalMetrics.isSelected()) {
g2dText.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS,
RenderingHints.VALUE_FRACTIONALMETRICS_ON);
} else {
g2dText.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS,
RenderingHints.VALUE_FRACTIONALMETRICS_OFF);
}
if (strokeControl.isSelected()) {
g2dText.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL,
RenderingHints.VALUE_STROKE_NORMALIZE);
} else {
g2dText.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL,
RenderingHints.VALUE_STROKE_PURE);
}
if (dithering.isSelected()) {
g2dText.setRenderingHint(RenderingHints.KEY_DITHERING,
RenderingHints.VALUE_DITHER_ENABLE);
} else {
g2dText.setRenderingHint(RenderingHints.KEY_DITHERING,
RenderingHints.VALUE_DITHER_DISABLE);
}
if (colorRendering.isSelected()) {
g2dText.setRenderingHint(RenderingHints.KEY_COLOR_RENDERING,
RenderingHints.VALUE_COLOR_RENDER_QUALITY);
} else {
g2dText.setRenderingHint(RenderingHints.KEY_COLOR_RENDERING,
RenderingHints.VALUE_COLOR_RENDER_SPEED);
}
g2dText.setRenderingHint(RenderingHints.KEY_TEXT_LCD_CONTRAST,
textLcdContrast.getSelectedItem());
g2dText.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
textAntialiasing.getSelectedItem());
g2dText.drawImage(originalImage, 0,0, null);
g2dText.setColor(Color.black);
g2dText.drawString("The quick brown fox jumped over the lazy dog.", 10,50);
Graphics2D g2dDifference = differenceImage.createGraphics();
Graphics2D g2dBnW = bnwImage.createGraphics();
for (int xx=0; xx<width; xx++) {
for (int yy=0; yy<height; yy++) {
Color originalColor = new Color(originalImage.getRGB(xx,yy));
int r1 = originalColor.getRed();
int g1 = originalColor.getGreen();
int b1 = originalColor.getBlue();
Color newColor = new Color(textImage.getRGB(xx,yy));
int r2 = newColor.getRed();
int g2 = newColor.getGreen();
int b2 = newColor.getBlue();
Color bnw = Color.black;
if (r1==r2 && g1==g2 && b1==b2) {
bnw = Color.white;
}
bnwImage.setRGB(xx, yy, bnw.getRGB());
int rD = Math.abs(r1-r2);
int gD = Math.abs(g1-g2);
int bD = Math.abs(b1-b2);
Color differenceColor = new Color(rD,gD,bD);
differenceImage.setRGB(xx, yy, differenceColor.getRGB());
}
}
gui.repaint();
}
public static void main(String[] args) {
SwingUtilities.invokeLater( new Runnable() {
public void run() {
ImageWriteTest iwt = new ImageWriteTest();
}
} );
}
}
In C/C++, if you're comfortable requiring a minimum version of Windows, it's rather easy, you can use GDI+ to load the image and draw it to a memory bitmap, then you can use the returned pointer to get the pixel data.
Use GdiplusStartup() and GdiplusShutdown() to initialise and uninitialise GDI+.
Use a GDI+ Image object, using the overload that takes a filename, to load the image, then use the methods GetWidth() and GetHeight(), a BITMAPINFO structure and the CreateDIBSection() GDI function to create a memory bitmap.
Then use CreateCompatibleDC() to create a device context for the bitmap and SelectObject() to select the bitmap into that device context.
Then you use a GDI+ Graphics object, using the overload that takes a device context, and its DrawImage() method, using the overload that takes x, y, width and height, to draw the image to the bitmap's device context.
After that, you can get/set the pixel data using the pointer returned by CreateDIBSection().
When you're done, use DeleteDC() to get rid of the bitmap's device context BEFORE using DeleteObject() to get rid of the bitmap. GDI+ Image objects can also be used to save images in a supported format, including PNG.