Convert jpg image to black and white?

U

Uli Kunkel

How can I convert an image to black and white?
Do I have to manually calculate each pixel or is there some class that
has this functionality?

Thanks for any suggestions.
 
B

blue indigo

How can I convert an image to black and white?
Do I have to manually calculate each pixel or is there some class that
has this functionality?

Thanks for any suggestions.

java.awt.image.ColorConvertOp with java.awt.color.ColorSpace.CS_GRAY ought
to do it.
 
U

Uli Kunkel

blue said:
java.awt.image.ColorConvertOp with java.awt.color.ColorSpace.CS_GRAY ought
to do it.

Thank you but I need only black and white, and this is gray scale.
Although I will first use this to convert it to gray scale first and
after that I will try to implement one of the existing algorithms.

Does anyone know of any good package that does the black&white conversion?
 
C

Casey Hawthorne

After converting to gray scale, you could set a threshold and all
pixels above that are white.
 
B

blue indigo

Thank you but I need only black and white, and this is gray scale.

I'm sorry, mate -- often when people say "black and white", greyscale is
actually what they have in mind.

Unfortunately, I don't see a true-monochrome java.awt.color.ColorSpace in
the standard library. You could convert to greyscale and threshold it.
That's a fairly simple iteration over the image pixels.
 
J

John B. Matthews

Katja Christiansen said:
You could also write your image to a BufferedImage of a given type:

BufferedImage blackAndWhiteImage =
new BufferedImage(originalImage.getWidth(null),
originalImage.getHeight(null), BufferedImage.TYPE_BYTE_BINARY);
Graphics2D g = (Graphics2D) blackAndWhiteImage.getGraphics();
g.drawImage(originalImage, 0, 0, null);
g.dispose();

Excellent!

<http://sites.google.com/site/trashgod/threshold>
 
U

Uli Kunkel

Katja said:
You could also write your image to a BufferedImage of a given type:

BufferedImage blackAndWhiteImage =
new BufferedImage(originalImage.getWidth(null),
originalImage.getHeight(null), BufferedImage.TYPE_BYTE_BINARY);
Graphics2D g = (Graphics2D) blackAndWhiteImage.getGraphics();
g.drawImage(originalImage, 0, 0, null);
g.dispose();

Katja


Thank you very much.
I tried this and it works, but I need better quality so I'll try some
dithering algorithm like Floyd-Steinberg.
I'm not yet sure how to implement it with java..
 
U

Uli Kunkel

Uli said:
How can I convert an image to black and white?
Do I have to manually calculate each pixel or is there some class that
has this functionality?

Thanks for any suggestions.

I have copied somebody's method and modified it.
It uses a dithering algorithm so it looks good.

The problem now is that I want to save a bmp image with a specified dpi
setting in the header.
I found that this can be done for jpeg with JPEGEncodeParam but nothing
for bmp.
So does anybody know hot to change the dpi when writing a bmp image?




Belove is the code for bw dithering:
------------------------------------------------------------------------------
public static BufferedImage processImage(BufferedImage inputImage) {

// Create a binary image for the results of processing

int w = inputImage.getWidth();
int h = inputImage.getHeight();
BufferedImage outputImage = new BufferedImage(w, h,
BufferedImage.TYPE_BYTE_BINARY);

// Work on a copy of input image because it is modified by diffusion

WritableRaster input = inputImage.copyData(null);
WritableRaster output = outputImage.getRaster();

final int threshold = 128;
float value, error;

for (int y = 0; y < h; ++y)
for (int x = 0; x < w; ++x) {

value = input.getSample(x, y, 0);

// Threshold value and compute error

if (value < threshold) {
output.setSample(x, y, 0, 0);
error = value;
}
else {
output.setSample(x, y, 0, 1);
error = value - 255;
}

// Spread error amongst neighbouring pixels

if((x > 0) && (y > 0) && (x < (w-1)) && (y < (h-1)))
{
value = input.getSample(x+1, y, 0);
input.setSample(x+1, y, 0, clamp(value + 0.4375f * error));
value = input.getSample(x-1, y+1, 0);
input.setSample(x-1, y+1, 0, clamp(value + 0.1875f * error));
value = input.getSample(x, y+1, 0);
input.setSample(x, y+1, 0, clamp(value + 0.3125f * error));
value = input.getSample(x+1, y+1, 0);
input.setSample(x+1, y+1, 0, clamp(value + 0.0625f * error));
}

}
return outputImage;

}

// Forces a value to a 0-255 integer range

public static int clamp(float value) {
return Math.min(Math.max(Math.round(value), 0), 255);
}
 
J

John B. Matthews

Uli Kunkel said:
Katja said:
You could also write your image to a BufferedImage of a given type:

BufferedImage blackAndWhiteImage =
new BufferedImage(originalImage.getWidth(null),
originalImage.getHeight(null), BufferedImage.TYPE_BYTE_BINARY);
Graphics2D g = (Graphics2D) blackAndWhiteImage.getGraphics();
g.drawImage(originalImage, 0, 0, null);
g.dispose();
[...]
Thank you very much.
I tried this and it works, but I need better quality so I'll try some
dithering algorithm like Floyd-Steinberg. I'm not yet sure how to
implement it with java..

Alternatively, you might experiment with these interpolation types and
the related rendering hints:

<http://java.sun.com/javase/6/docs/api/java/awt/image/AffineTransformOp.html>
<http://java.sun.com/javase/6/docs/api/java/awt/RenderingHints.html>
 
U

Uli Kunkel

John said:
Uli Kunkel said:
Katja said:
How can I convert an image to black and white? Do I have to
manually calculate each pixel or is there some class that has this
functionality?

Thanks for any suggestions.
You could also write your image to a BufferedImage of a given type:

BufferedImage blackAndWhiteImage =
new BufferedImage(originalImage.getWidth(null),
originalImage.getHeight(null), BufferedImage.TYPE_BYTE_BINARY);
Graphics2D g = (Graphics2D) blackAndWhiteImage.getGraphics();
g.drawImage(originalImage, 0, 0, null);
g.dispose();
[...]
Thank you very much.
I tried this and it works, but I need better quality so I'll try some
dithering algorithm like Floyd-Steinberg. I'm not yet sure how to
implement it with java..

Alternatively, you might experiment with these interpolation types and
the related rendering hints:

<http://java.sun.com/javase/6/docs/api/java/awt/image/AffineTransformOp.html>
<http://java.sun.com/javase/6/docs/api/java/awt/RenderingHints.html>

The code that I posted works good enough.
Now my problem is that I don't know how to set the DPI settings in the
header of the bmp file.
 
J

John B. Matthews

Uli Kunkel said:
John said:
Uli Kunkel said:
Katja Christiansen wrote:
How can I convert an image to black and white? Do I have to
manually calculate each pixel or is there some class that has this
functionality?

Thanks for any suggestions.
You could also write your image to a BufferedImage of a given type:

BufferedImage blackAndWhiteImage =
new BufferedImage(originalImage.getWidth(null),
originalImage.getHeight(null), BufferedImage.TYPE_BYTE_BINARY);
Graphics2D g = (Graphics2D) blackAndWhiteImage.getGraphics();
g.drawImage(originalImage, 0, 0, null);
g.dispose(); [...]
Thank you very much.
I tried this and it works, but I need better quality so I'll try some
dithering algorithm like Floyd-Steinberg. I'm not yet sure how to
implement it with java..

Alternatively, you might experiment with these interpolation types and
the related rendering hints:

<http://java.sun.com/javase/6/docs/api/java/awt/image/AffineTransformOp.html<http://java.sun.com/javase/6/docs/api/java/awt/RenderingHints.html>

The code that I posted works good enough.

Ah, the magic numbers look like Floyd-Steinberg:

<http://en.wikipedia.org/wiki/Floyd-Steinberg_dithering>
<http://en.wikipedia.org/wiki/Magic_number_(programming)>

You might want to consider expanding the comments, in case the forlorn
maintainer ends up being you.

Here's a thoughtful paper comparing several techniques included in
AffineTransformOp, mentioned above:

Now my problem is that I don't know how to set the DPI settings in the
header of the bmp file.

I'd have thought that would depend on the source. I suppose you could
always post-process the file's header:

<http://en.wikipedia.org/wiki/BMP_file_format>

Little-endian pixels per meter? Who knew!
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,754
Messages
2,569,525
Members
44,997
Latest member
mileyka

Latest Threads

Top