Reputation: 3424
I have written one application for image processing in Java. I have processed the image which is the buffered image and now I want to return the byte[]
for that processed image that is I should get the byte array of binarized image.
Here is my code:
public static byte[][] binarizeImage(BufferedImage bfImage){
int red;
int newPixel;
int h ;
int w ;
int threshold = otsuTreshold(bfImage);
// this function returns the threshold value 199
BufferedImage binarized = new BufferedImage(bfImage.getWidth(), bfImage.getHeight(), bfImage.getType());
for(int i=0; i<bfImage.getWidth(); i++) {
for(int j=0; j<bfImage.getHeight(); j++) {
// Get pixels
red = new Color(bfImage.getRGB(i, j)).getRed();
int alpha = new Color(bfImage.getRGB(i, j)).getAlpha();
if(red > threshold) {
newPixel = 255;
}
else {
newPixel = 0;
}
newPixel = colorToRGB(alpha, newPixel, newPixel, newPixel);
binarized.setRGB(i, j, newPixel);
}
}
Raster raster = binarized.getData();
h = raster.getHeight();
w = raster.getWidth();
byte[][] binarize_image = new byte[w][h];
for(int i=0 ; i<w ; i++)
{
for(int j=0; j<h ; j++)
{
binarize_image[i][j]=raster.getSampleModel(); //error at this line
}
}
return binarize_image;
}
// Convert R, G, B, Alpha to standard 8 bit
private static int colorToRGB(int alpha, int red, int green, int blue) {
int newPixel = 0;
newPixel += alpha;
newPixel = newPixel << 8;
newPixel += red; newPixel = newPixel << 8;
newPixel += green; newPixel = newPixel << 8;
newPixel += blue;
return newPixel;
}
But it is not working. What should I do to convert that buffered image to byte array for the same image data?
Upvotes: 2
Views: 5388
Reputation: 1747
try {
// get the BufferedImage, using the ImageIO class
Bitmap image =
BitmapFactory.decodeStream(getAssets()
.open("aa.bmp"));
marchThroughImage(image);
} catch (IOException e) {
System.err.println(e.getMessage());
}
}
});
}
public void printPixelARGB(int pixel) {
int alpha = (pixel >> 24) & 0xff;
int red = (pixel >> 16) & 0xff;
int green = (pixel >> 8) & 0xff;
int blue = (pixel) & 0xff;
System.out.println("argb: " + alpha + ", " + red + ", " + green + ", " + blue);
}
private void marchThroughImage(Bitmap image) {
int w = image.getWidth();
int h = image.getHeight();
System.out.println("width, height: " + w + ", " + h);
for (int i = 0; i < h; i++) {
for (int j = 0; j < w; j++) {
System.out.println("x,y: " + j + ", " + i);
int pixel = image.getPixel(j, i);
printPixelARGB(pixel);
System.out.println("");
}
}
}
Upvotes: 1
Reputation: 27113
How about:
BufferedImage input;
BufferedImage binary = new BufferedImage(input.getWidth(), input.getHeight(), BufferedImage.TYPE_BYTE_BINARY);
Graphics2D g = binary.createGraphics();
try {
g.drawImage(input, 0, 0, null);
}
finally {
g.dispose();
}
It will not use your otsuTreshold
, and it will (probably) dither the image, but it will do the job of making it binary (black/white only), using a minimal amount of memory.
Upvotes: 1
Reputation: 4826
I am not sure what the term "binarize" means at this context. You seem to just want to filter the image (i.e. cutt-off the red channel based on some threshold) and convert the result to a byte[]
.
Assuming the above is correct then check the code below. It will convert the image to a byte[]
for a 32-bit image. Please take into account the following:
byte[]
. You can do that during the conversion. byte[]
would have a size of 4 * width * height
not width * height
assuming we are talking about the case of a 32-bit image. If you need to handle other cases you should take into account the available image types supported by the BufferedImage
(or at least only the ones you are interested in).The code below will print information for each converted pixel like below (Note how the red channel is filtered):
[0,0] Converting [ffaaccee] --> [0, cc, ee, ff]
package imageio.byteconversion;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.InputStream;
import javax.imageio.ImageIO;
public class BufferedImageToBytes {
private static void log(String s) {
System.out.println(s);
}
private static String toByteString(int color) {
// Perform a bitwise AND for convenience while printing.
// Otherwise Integer.toHexString() interprets values as integers and a negative byte 0xFF will be printed as "ffffffff"
return Integer.toHexString(color & 0xFF);
}
public static void main(String[] args) throws IOException {
// Load the image. This expects the image to be in the same package with this class
InputStream stream = BufferedImageToBytes.class.getResourceAsStream("test.png");
BufferedImage image = ImageIO.read(stream);
int iw = image.getWidth();
int ih = image.getHeight();
log("Image loaded succesfully, width=" + iw + " height=" + ih);
stream.close();
log("Image color model: " + image.getColorModel());
log("Image sample model: " + image.getSampleModel());
log("Image raster: " + image.getRaster());
int bands = image.getSampleModel().getNumBands();
log("Color bands: " + bands);
if (bands != 4) {
throw new RuntimeException("The image does not have 4 color bands. Are you sure this is a 32-bit image?");
}
int threshold = 199; // <-- decide your threshold here
byte bytes[] = new byte[4 * iw * ih];
int index = 0;
// note that image is processed row by row top to bottom
for(int y = 0; y < ih; y++) {
for(int x = 0; x < iw; x++) {
// returns a packed pixel where each byte is a color channel
// order is the default ARGB color model
int pixel = image.getRGB(x, y);
// Get pixels
int alpha = (pixel >> 24) & 0xFF;
int red = (pixel >> 16) & 0xFF;
int green = (pixel >> 8) & 0xFF;
int blue = pixel & 0xFF;
// perform filtering here depending on threshold
if (red > threshold) {
red = 255;
} else {
red = 0;
}
log("[" + x + "," + y + "]" + " Converting [" + Integer.toHexString(pixel) + "] --> ["
+ toByteString(red) + ", " + toByteString(green) + ", "
+ toByteString(blue) + ", " + toByteString(alpha)
+ "]");
bytes[index++] = (byte) red;
bytes[index++] = (byte) green;
bytes[index++] = (byte) blue;
bytes[index++] = (byte) alpha;
}
}
}
}
Upvotes: 2