Java outputting an image to grayscale and sepia - java

I am trying to read an image and output it as new grayscale and sepia version. I have figured out most of it, but the conversion only works for some images. For others, it just leads to an error message:
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: Coordinate out of bounds!
at sun.awt.image.ByteInterleavedRaster.getDataElements(ByteInterleavedRaster.java:318)
at java.awt.image.BufferedImage.getRGB(BufferedImage.java:918)
at ChangeColor.color2gray(ChangeColor.java:64)
at ChangeColor.main(ChangeColor.java:129)
I think it has something to do with the rgb values of the images, but I'm not sure how to adjust that to make this code work for any image. Help would be appreciated, thank you.
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import javax.imageio.IIOImage;
import javax.imageio.ImageIO;
import javax.imageio.ImageWriteParam;
import javax.imageio.ImageWriter;
import javax.imageio.plugins.jpeg.JPEGImageWriteParam;
import javax.imageio.stream.ImageOutputStream;
public class ChangeColor{
static BufferedImage readImage( String fname ) throws Exception {
BufferedImage image = ImageIO.read( new File(fname) );
return( image );
}
public static void saveImage( BufferedImage img, File file ) throws IOException {
ImageWriter writer = null;
java.util.Iterator iter = ImageIO.getImageWritersByFormatName("jpg");
if( iter.hasNext() ){
writer = (ImageWriter)iter.next();
}
ImageOutputStream ios = ImageIO.createImageOutputStream( file );
writer.setOutput(ios);
ImageWriteParam param = new JPEGImageWriteParam( java.util.Locale.getDefault() );
param.setCompressionMode(ImageWriteParam.MODE_EXPLICIT) ;
param.setCompressionQuality(0.98f);
writer.write(null, new IIOImage( img, null, null ), param);
}
public static BufferedImage color2gray( BufferedImage inImage ) {
int width = inImage.getWidth();
int height = inImage.getHeight();
BufferedImage outImage = new BufferedImage( width, height, BufferedImage.TYPE_3BYTE_BGR );
for(int i=0; i<height; i++){
for(int j=0; j<width; j++){
{
int pic= inImage.getRGB(i,j);
int in_r = ((pic>>16) & 0xFF);
int in_g = ((pic>>8) & 0xFF);
int in_b = (pic & 0xFF);
float gray = (float)(in_r * 0.2126 + in_g * 0.7152 + in_b * 0.0722)/256;
Color color = new Color (gray, gray, gray);
int RGB = color.getRGB();
outImage.setRGB (i,j,RGB);
}
}
}
return( outImage );
}
public static BufferedImage color2sepia( BufferedImage inImage ) {
int width = inImage.getWidth();
int height = inImage.getHeight();
BufferedImage outImage = new BufferedImage( width, height, BufferedImage.TYPE_3BYTE_BGR );
for(int i=0; i<height; i++){
for(int j=0; j<width; j++){
{
int pic= inImage.getRGB(i,j);
int in_r = ((pic>>16) & 0xFF);
int in_g = ((pic>>8) & 0xFF);
int in_b = (pic & 0xFF);
float out_r = (float)(((in_r * .393) + (in_g *.769) + (in_b * .189))/256);
if (out_r>1)
out_r = 1;
float out_g = (float)(((in_r * .349) + (in_g *.686) + (in_b * .168))/256);
if (out_g>1)
out_g = 1;
float out_b = (float)(((in_r * .272) + (in_g *.534) + (in_b * .131))/256);
if (out_b>1)
out_b = 1;
Color color = new Color (out_r, out_g, out_b);
int RGB = color.getRGB();
outImage.setRGB (i,j,RGB);
}
}
}
return( outImage );
}
public static void main(String[] args) throws Exception {
BufferedImage colorImage, grayImage, sepiaImage;
if (args.length != 1)
System.out.println( "usage is: java ChangeColor filename" );
else
{
colorImage = readImage ( args[0] );
grayImage = color2gray ( colorImage );
sepiaImage = color2sepia( colorImage );
saveImage( grayImage, new File( "gray" + args[0] ) );
saveImage( sepiaImage, new File( "sepia"+ args[0] ) );
}
}
}

Your error is here:
for(int i=0; i<height; i++){
for(int j=0; j<width; j++){
{
int pic= inImage.getRGB(i,j);
You have swapped width and height, so you unless the image is a perfect square you will get the error you posted.

Related

How to recognize an image in another image?

So I'm fairly new to Java, so I'm not sure that this my method of doing this is actually a good idea, but basically I am trying to check for an instance of an image inside another image. So for my testing to see if this would work, I had a 200x148 jpg, got the bytes from that, then got the bytes from a screenshot of the window, and got the bytes from that, and then compared them.
Now, since normally the first image wouldn't be in that screenshot, I opened it in my photos app and put it in while the program was sleeping (before it took the screenshot). And yes, I can confirm that the first image was in the screenshot by looking at the screenshot. However, when I compare the strings (to check if a String with all of the byte data of image one is in a String with all of the byte data of image two), it turns out negative.
Here's the code that I'm trying to use so far:
public static void main(String[] args) throws IOException, HeadlessException, AWTException, InterruptedException {
// Get the first image
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ImageIO.write(ImageIO.read(new File("profile.jpg")), "jpg", baos);
byte[] bytes = baos.toByteArray();
String bytes1S = "";
for (int i = 0; i < bytes.length; i++) {
bytes1S += bytes[i];
}
// Give yourself enough time to open the other image
TimeUnit.SECONDS.sleep(6);
// Take the screenshot
BufferedImage image = new Robot().createScreenCapture(new Rectangle(Toolkit.getDefaultToolkit().getScreenSize()));
ImageIO.write(image, "jpg", new File("screenshot.jpg"));
baos = new ByteArrayOutputStream();
ImageIO.write(ImageIO.read(new File("screenshot.jpg")), "jpg", baos);
byte[] bytes2 = baos.toByteArray();
String bytes2S = "";
for (int i = 0; i < bytes2.length; i++) {
bytes2S += bytes2[i];
}
// Check if the second String of bytes contains the first String of bytes.
if (bytes2S.contains(bytes1S))
System.out.println("Yes");
else
System.out.println("No");
}
And for reference, here's the first image, and the screenshot that it took:
What's the reason behind it not detecting the first image in the screenshot, and is there a better way to do this (preferably without another library)?
A brute-force approach is to simply load both images as BufferedImage objects, and then walk through the "main" image, pixel by pixel, and see if the "sub image" can be found there.
I have implemented this a while ago, and will post the code below as a MCVE.
But note: When you save images as JPG files, then they are compressed, and this compression is lossy. This means that the pixels will not have the perfectly same colors, even if they have been equal on the screen. In the example below, this is solved pragmatically, with a "threshold" that defines how different the pixels may be. But this is a bit arbitrary and not so reliable. (A more robust solution would require more effort).
I'd strongly recommend to save the images as PNG files. They use a lossless compression. So for PNG files, you can set threshold=0 in the code below.
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.image.BufferedImage;
import java.net.URL;
import java.util.function.IntBinaryOperator;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class FindImageInImage
{
public static void main(String[] args) throws Exception
{
BufferedImage mainImage =
ImageIO.read(new URL("https://i.stack.imgur.com/rEouF.jpg"));
BufferedImage subImage =
ImageIO.read(new URL("https://i.stack.imgur.com/wISyn.jpg"));
int threshold = 100;
Point location = findImageLocation(
mainImage, subImage, threshold);
System.out.println("At " + location);
SwingUtilities.invokeLater(() -> showIt(mainImage, subImage, location));
}
private static void showIt(
BufferedImage mainImage, BufferedImage subImage, Point location)
{
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.getContentPane().add(new JPanel()
{
#Override
protected void paintComponent(Graphics g)
{
super.paintComponent(g);
g.drawImage(mainImage, 0, 0, null);
if (location != null)
{
g.setColor(Color.RED);
g.drawRect(location.x, location.y,
subImage.getWidth(), subImage.getHeight());
}
}
});
f.setSize(1500, 800);
f.setLocationRelativeTo(null);
f.setVisible(true);
}
static Point findImageLocation(
BufferedImage mainImage,
BufferedImage subImage,
int threshold)
{
return findImageLocation(mainImage, subImage, (rgb0, rgb1) ->
{
int difference = computeDifference(rgb0, rgb1);
if (difference > threshold)
{
return 1;
}
return 0;
});
}
private static int computeDifference(int rgb0, int rgb1)
{
int r0 = (rgb0 & 0x00FF0000) >> 16;
int g0 = (rgb0 & 0x0000FF00) >> 8;
int b0 = (rgb0 & 0x000000FF);
int r1 = (rgb1 & 0x00FF0000) >> 16;
int g1 = (rgb1 & 0x0000FF00) >> 8;
int b1 = (rgb1 & 0x000000FF);
int dr = Math.abs(r0 - r1);
int dg = Math.abs(g0 - g1);
int db = Math.abs(b0 - b1);
return dr + dg + db;
}
static Point findImageLocation(
BufferedImage mainImage,
BufferedImage subImage,
IntBinaryOperator rgbComparator)
{
int w = mainImage.getWidth();
int h = mainImage.getHeight();
for (int x=0; x < w; x++)
{
for (int y = 0; y < h; y++)
{
if (isSubImageAt(mainImage, x, y, subImage, rgbComparator))
{
return new Point(x, y);
}
}
}
return null;
}
static boolean isSubImageAt(
BufferedImage mainImage, int x, int y,
BufferedImage subImage,
IntBinaryOperator rgbComparator)
{
int w = subImage.getWidth();
int h = subImage.getHeight();
if (x + w > mainImage.getWidth())
{
return false;
}
if (y + h > mainImage.getHeight())
{
return false;
}
for (int ix=0; ix < w; ix++)
{
for (int iy = 0; iy < h; iy++)
{
int mainRgb = mainImage.getRGB(x + ix, y + iy);
int subRgb = subImage.getRGB(ix, iy);
if (rgbComparator.applyAsInt(mainRgb, subRgb) != 0)
{
return false;
}
}
}
return true;
}
}

How can I control the brightness of an Image?

I have the following problem:
I want to create a method to control the brightness of an Image. I think I have to convert it to a BufferedImage before.
And if the Image has an alpha channel and I want to convert it with TYPE_INT_RGB the alpha pixels will be black. But it works fine with TYPE_INT_ARGB...
It doesn't work if the image doesn't have an alpha channel and I convert it with TYPE_INT_ARGB. Then not only the brightness changes, but also the color. When I make the image brighter it becomes more yellow an it becomes blue if I darken it.
Can I convert it in another way or is there a possibility to check if the Image has an alpha channel?
Here is my code:
public static Image brightnessControl(Image image, float brightness) {
//First I convert the Image to a BufferedImage
BufferedImage bi = new BufferedImage
(image.getWidth(null), image.getHeight(null), BufferedImage.TYPE_INT_ARGB);
Graphics bg = bi.getGraphics();
bg.drawImage(image, 0, 0, null);
bg.dispose();
//here I brighten/darken the BufferedImage
RescaleOp rescaleOp = new RescaleOp(brightness, 0, null);
rescaleOp.filter(bi, bi);
//I change the BufferedImage back to the Image again!
image = bi;
//Last but not least I return the Image...
return image;
}
Take a look in the code below.
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Test {
public static void main( String[] args ) throws IOException {
Image img = ImageIO.read( new File( "image.jpeg" ) );
new JFrame(){
{
setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
setSize( 800, 600 );
setLocationRelativeTo( null );
add( new JPanel(){
#Override
protected void paintComponent( Graphics g ) {
super.paintComponent( g );
int imgWidth = img.getWidth( null );
int imgHeight = img.getHeight( null );
int lines = 4;
int columns = 6;
int count = 1;
for ( int i = 0; i < lines; i++ ) {
for ( int j = 0; j < columns; j++ ) {
g.drawImage( newBrightness( img, 1f/(lines*columns)*count ), imgWidth * j, imgHeight * i, null );
count++;
}
}
}
});
}
}.setVisible( true );
}
public static Image newBrightness( Image source, float brightnessPercentage ) {
BufferedImage bi = new BufferedImage(
source.getWidth( null ),
source.getHeight( null ),
BufferedImage.TYPE_INT_ARGB );
int[] pixel = { 0, 0, 0, 0 };
float[] hsbvals = { 0, 0, 0 };
bi.getGraphics().drawImage( source, 0, 0, null );
// recalculare every pixel, changing the brightness
for ( int i = 0; i < bi.getHeight(); i++ ) {
for ( int j = 0; j < bi.getWidth(); j++ ) {
// get the pixel data
bi.getRaster().getPixel( j, i, pixel );
// converts its data to hsb to change brightness
Color.RGBtoHSB( pixel[0], pixel[1], pixel[2], hsbvals );
// create a new color with the changed brightness
Color c = new Color( Color.HSBtoRGB( hsbvals[0], hsbvals[1], hsbvals[2] * brightnessPercentage ) );
// set the new pixel
bi.getRaster().setPixel( j, i, new int[]{ c.getRed(), c.getGreen(), c.getBlue(), pixel[3] } );
}
}
return bi;
}
}
It will read a image and create a matrix with new images with new brightnesses. Here is the result for my profile image.
EDIT:
Now it supports alpha too. In the previous code, the alpha component of the new pixel was fixed in 255. I changed to use the alpha component of the original pixel (pixel[3]).
EDIT 2:
Each pixel will have a brightness component that varies from 0 to 1. If this component extrapolates the value 1, the pixel will have a "strange" color. You want to have something that seems brighter than the original one, so, you will need to verify if the new brightness value extrapolates 1. The example above will do this. You will have an slider to control what is the maximum percentage that will be calculated to the new pixel brightness component. If this value passes the maximum value (1), the maximum value will be used. I hope that now it finally helps you :D
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JSlider;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
public class ChangeImageBrightnessExample2 {
public static void main( String[] args ) throws IOException {
new ChangeImageBrightnessExample2().createUI();
}
public void createUI() throws IOException {
Image img = ImageIO.read( new File( "image.jpeg" ) );
new JFrame(){
{
setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
setSize( 800, 600 );
setLocationRelativeTo( null );
CustomPanel panel = new CustomPanel();
panel.setImage( img );
JSlider slider = new JSlider( 0, 400, 100 );
slider.setMinorTickSpacing( 10);
slider.setMajorTickSpacing( 50 );
slider.setPaintLabels( true );
slider.setPaintTicks( true );
slider.setSnapToTicks( true );
slider.addChangeListener( new ChangeListener() {
#Override
public void stateChanged( ChangeEvent evt ) {
JSlider s = ((JSlider) evt.getSource());
if ( s.getValueIsAdjusting() ) {
panel.setMaximumBrightnessPercentage( s.getValue()/100f );
panel.repaint();
}
}
});
add( panel, BorderLayout.CENTER );
add( slider, BorderLayout.SOUTH );
}
}.setVisible( true );
}
public static Image newBrightness( Image source, float brightnessPercentage ) {
BufferedImage bi = new BufferedImage(
source.getWidth( null ),
source.getHeight( null ),
BufferedImage.TYPE_INT_ARGB );
int[] pixel = { 0, 0, 0, 0 };
float[] hsbvals = { 0, 0, 0 };
bi.getGraphics().drawImage( source, 0, 0, null );
// recalculare every pixel, changing the brightness
for ( int i = 0; i < bi.getHeight(); i++ ) {
for ( int j = 0; j < bi.getWidth(); j++ ) {
// get the pixel data
bi.getRaster().getPixel( j, i, pixel );
// converts its data to hsb to change brightness
Color.RGBtoHSB( pixel[0], pixel[1], pixel[2], hsbvals );
// calculates the brightness component.
float newBrightness = hsbvals[2] * brightnessPercentage;
if ( newBrightness > 1f ) {
newBrightness = 1f;
}
// create a new color with the new brightness
Color c = new Color( Color.HSBtoRGB( hsbvals[0], hsbvals[1], newBrightness ) );
// set the new pixel
bi.getRaster().setPixel( j, i, new int[]{ c.getRed(), c.getGreen(), c.getBlue(), pixel[3] } );
}
}
return bi;
}
private class CustomPanel extends JPanel {
private float maximumBrightnessPercentage = 1f;
private Image image;
#Override
protected void paintComponent( Graphics g ) {
super.paintComponent( g );
int imgWidth = image.getWidth( null );
int imgHeight = image.getHeight( null );
int lines = 4;
int columns = 6;
int count = 1;
for ( int i = 0; i < lines; i++ ) {
for ( int j = 0; j < columns; j++ ) {
float newBrightness = maximumBrightnessPercentage/(lines*columns)*count;
g.drawImage( newBrightness( image, newBrightness ), imgWidth * j, imgHeight * i, null );
g.drawString( String.format( "%.2f%%", newBrightness*100 ), imgWidth * j, imgHeight * i + 10 );
count++;
}
}
}
public void setMaximumBrightnessPercentage( float maximumBrightnessPercentage ) {
this.maximumBrightnessPercentage = maximumBrightnessPercentage;
}
public void setImage( Image image ) {
this.image = image;
}
}
}
Take a look in the image below.
I think now you will understand. If not, I will give up :D
To check of the alpha channel in a BufferedImage, use BufferedImage.getColorModel().hasAlpha();
public static Image brightnessControl(Image image, float brightness) {
// First I convert the Image to a BufferedImage
BufferedImage bi = new BufferedImage(image.getWidth(null), image.getHeight(null), BufferedImage.TYPE_INT_ARGB);
Graphics bg = bi.getGraphics();
if (bi.getColorModel().hasAlpha()) { // This will output true because you have just applied TYPE_INT_ARGB!
System.out.println("Image has got an alpha channel");
}
bg.drawImage(image, 0, 0, null);
bg.dispose();
// here I brighten/darken the BufferedImage
RescaleOp rescaleOp = new RescaleOp(brightness, 0, null);
rescaleOp.filter(bi, bi);
// I change the BufferedImage back to the Image again!
image = bi;
// Last but not least I return the Image...
return bi;
}
You need to cast the Image passed in argument to BufferedImage to use the .getColorModel().hasAlpha() methods.

Convert pixel data back to image in Java

I have a code that puts an image in a pixel matrix.I have to split this image into four parts and get 4 different image files for these parts.
Then I have to do some image processing on it and then join those parts back together in a single image.
Please help me in achieving this.
Note:the image is colored and we want to just split it into 4 equal parts and then get it back as one.No changes needed.Here is the code to get four matrices of intensities.But I don't know what to do with it.It might be that there is no need of it at all.
import java.awt.image.BufferedImage;
import java.awt.image.DataBufferByte;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
class Optimization
{
public static void main(String[] args) throws IOException
{
BufferedImage hugeImage = ImageIO.read(new File("comp.jpg"));
final byte[] pixels = ((DataBufferByte) hugeImage.getRaster().getDataBuffer()).getData();
int width = hugeImage.getWidth();
int height = hugeImage.getHeight();
if(width%2!=0)
width=width-1;
if(height%2!=0)
height=height-1;
//System.out.print(width+" "+height);
int intensity[][]=new int[width][height];
int b1[][]=new int[width/2][height/2];
int b2[][]=new int[width/2][height/2];
int b3[][]=new int[width/2][height/2];
int b4[][]=new int[width/2][height/2];
int x1=0,y1=0,x2=0,y2=0,x3=0,x4=0,y3=0,y4=0;
final int pixelLength = 3;
for (int pixel = 0, row = 0, col = 0; pixel < pixels.length; pixel += pixelLength)
{
int a1,a2,a3;
a3= ((int) pixels[pixel] & 0xff); // blue
a2= (((int) pixels[pixel + 1] & 0xff)); // green
a1= (((int) pixels[pixel + 2] & 0xff)); // red
int i=(a1+a2+a3)/3;
intensity[col][row]=i;
if((col<=width/2-1)&&(row<=height/2-1))
{
b1[x1][y1]=i;
x1++;
if(col==width/2-1)
{
x1=0;
y1++;
}
}
if((col<width)&&(row<=height/2-1)&&(col>width/2-1))
{
b2[x2][y2]=i;
x2++;
if(col==width-1)
{
x2=0;
y2++;
}
}
if((col<width/2)&&(row<height)&&(row>=height/2))
{
b3[x3][y3]=i;
x3++;
if(col==width/2-1)
{
x3=0;
y3++;
}
}
if((col>width/2-1)&&(row>height/2-1))
{
b4[x4][y4]=i;
x4++;
if(col==width-1)
{
x4=0;
y4++;
}
}
col++;
if (col == width)
{
col = 0;
row++;
}
}
for(int m=0;m<height/2;m++)
{
for(int n=0;n<width/2;n++)
{
System.out.print(b1[n][m]+" ");
}
System.out.println();
}
}
}
java.awt.Image provides you getSubimage(int x, int y, int w, int h)
"Returns a subimage defined by a specified rectangular region." You just return four equal regions and thats it.
You can use getSubImage(int x, int y, int w, int h), but you will get an image that shares the same raster than the original image, meaning that if you modify the new sub-image, then you also modify the original image. If it's not problematic for you, then use it.
Else, as you have already accessed the DataBuffer (good idea), here is a simple code to do what you want (I just make DataBuffer copies, and it works when the image dimensions are odd):
BufferedImage image = ... ;
BufferedImage q1 = new BufferedImage(image.getWidth()/2, image.getHeight()/2, image.getType()) ;
BufferedImage q2 = new BufferedImage(image.getWidth()-image.getWidth()/2, image.getHeight()/2, image.getType()) ;
BufferedImage q3 = new BufferedImage(image.getWidth()/2, image.getHeight()-image.getHeight()/2, image.getType()) ;
BufferedImage q4 = new BufferedImage(image.getWidth()-image.getWidth()/2, image.getHeight()-image.getHeight()/2, image.getType()) ;
byte[] bb = ((DataBufferByte)image.getRaster().getDataBuffer()).getData() ;
byte[] bbq1 = ((DataBufferByte)q1.getRaster().getDataBuffer()).getData() ;
byte[] bbq2 = ((DataBufferByte)q2.getRaster().getDataBuffer()).getData() ;
byte[] bbq3 = ((DataBufferByte)q3.getRaster().getDataBuffer()).getData() ;
byte[] bbq4 = ((DataBufferByte)q4.getRaster().getDataBuffer()).getData() ;
for (int y=0 ; y < q1.getHeight() ; y++) // Fill Q1 and Q2
{
System.arraycopy(bb, y*image.getWidth(), bbq1, y*q1.getWidth(), q1.getWidth()) ;
System.arraycopy(bb, y*image.getWidth()+q1.getWidth(), bbq2, y*q2.getWidth(), q2.getWidth()) ;
}
for (int y=0 ; y < q3.getHeight() ; y++) // Fill Q3 and Q4
{
System.arraycopy(bb, (y+q1.getHeight())*image.getWidth(), bbq3, y*q3.getWidth(), q3.getWidth()) ;
System.arraycopy(bb, (y+q1.getHeight())*image.getWidth()+q3.getWidth(), bbq4, y*q4.getWidth(), q4.getWidth()) ;
}

Converting BufferedImage to binary without image going completely black

i am trying to create an OCR to read 7 segment led off of old camera reals. this is my pre processing (ignore the random imports been trying a bunch of options)right now i am changing the image to negative from orange and gray and changing it to Grayscale, once i try to change gray scale to binary it just blacks out the image and i have no clue to remedy it with this code.
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.color.*;
import java.awt.image.BufferedImage;
import java.awt.image.ColorConvertOp;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
public class PreProcess2 {
public static void main(String [] args) {
BufferedImage img = null;
File dir = new File ("Directory/file/example photo");
File[] dirList = dir.listFiles();
for (int i = 1; i < dirList.length; i++) {
try{
img = ImageIO.read(dirList[i].getAbsoluteFile());
int d = 2;
int iw = img.getWidth();
int ih = img.getHeight();
int xb = ((((iw/d)/d)+(iw/d)));
int yb = ((((ih/d)/d)+(ih/d)));
try {
//Isolates Width
for (int x = xb ; x <= (iw-1); x++){
//Isolates Height
for (int y = yb; y <= (ih-1); y++){
int p = img.getRGB(x, y);
int a = (p>>24)&0xff;
int r = (p>>16)&0xff;
int g = (p>>8)&0xff;
int b = p&0xff;
//subtract RGB from 255
r = 255 - r;
g = 255 - g;
b = 255 - b;
//set new RGB from 255
p = (a<<24) | (r<<16) | (g<<8) | b;
img.setRGB(x, y, p);
}
}
//Prints out if pixel is out of bounds
}catch (ArrayIndexOutOfBoundsException e) {
System.out.println("out of bounds");
}
BufferedImage result = new BufferedImage(
img.getWidth(),
img.getHeight(),
BufferedImage.TYPE_BYTE_GRAY);
Graphics g = result.getGraphics();
g.drawImage(img, 0, 0, null);
g.dispose();
BufferedImage gray = new BufferedImage(result.getWidth(), result.getHeight(),
BufferedImage.TYPE_BYTE_BINARY);
BufferedImage croppedImage = gray.getSubimage(615, 445, 110, 35);
//Saves file to processed file location
File outputfile = new File(dir +"/Processed/" + dirList[i].getName());
ImageIO.write(croppedImage, "jpg", outputfile);
//Print out if not able to retrieve file
} catch (IOException e) {
System.out.println("Done");
}
}
}
}
Blacked out
Negative
UPDATE:
BufferedImage binary = new BufferedImage(iw, ih, BufferedImage.TYPE_BYTE_BINARY);
Graphics biG = binary.getGraphics();
biG.drawImage(gray, 0, 0, null);
biG.dispose();
managed to find a partial answer with the help of a colleague now i need to figure out how to clean up the noise in the images, any ideas?

Error in writing a grayscale image

In the following code am trying to read a grayscale image, store the pixel values in a 2D array and rewrite the image with a different name.
The code is
package dct;
import java.awt.image.BufferedImage;
import java.awt.image.DataBufferByte;
import java.awt.image.Raster;
import java.io.File;
import javax.imageio.ImageIO;
public class writeGrayScale
{
public static void main(String[] args)
{
File file = new File("lightning.jpg");
BufferedImage img = null;
try
{
img = ImageIO.read(file);
}
catch(Exception e)
{
e.printStackTrace();
}
int width = img.getWidth();
int height = img.getHeight();
int[][] arr = new int[width][height];
Raster raster = img.getData();
for (int i = 0; i < width; i++)
{
for (int j = 0; j < height; j++)
{
arr[i][j] = raster.getSample(i, j, 0);
}
}
BufferedImage image = new BufferedImage(256, 256, BufferedImage.TYPE_BYTE_GRAY);
byte[] raster1 = ((DataBufferByte) image.getRaster().getDataBuffer()).getData();
System.arraycopy(arr,0,raster1,0,raster1.length);
//
BufferedImage image1 = image;
try
{
File ouptut = new File("grayscale.jpg");
ImageIO.write(image1, "jpg", ouptut);
}
catch(Exception e)
{
e.printStackTrace();
}
}// main
}// class
For this code , the error is
Exception in thread "main" java.lang.ArrayStoreException
at java.lang.System.arraycopy(Native Method)
at dct.writeGrayScale.main(writeGrayScale.java:49)
Java Result: 1
How to remove this error to write the grayscale image?
I found this: "ArrayStoreException -- if an element in the src array could not be stored into the dest array because of a type mismatch." http://www.tutorialspoint.com/java/lang/system_arraycopy.htm
Two thoughts:
You're copying an int-array into a byte-array.
That's not part of the exceptions, but are the dimensions right? arr is a two-dimensional array, raster1 is a one-dimensional array.
And you can't just change the byte-array in a two-dimensional one ignoring the output of the method you're calling.
Change int[][] arr to byte[] arr like this.
byte[] arr = new byte[width * height * 4];
for (int i = 0, z = 0; i < width; i++) {
for (int j = 0; j < height; j++, z += 4) {
int v = getSample(i, j, 0);
for (int k = 3; k >= 0; --k) {
arr[z + k] = (byte)(v & 0xff);
v >>= 8;
}
}
}

Categories

Resources