I want to transfer my bytearray into a binary image
But I don't how to do it.
array value only have 0 and 1.
0 = black , 1 = white,
byte [] arr = new byte[32*32];
for(int i=0;i<arr.length;i++){
arr[i]= i%2==0?(byte)0:(byte)1
}
please help me , thanks
It depends on what you are going to do with that binary image.
If you only need it for your computation, your array may do the job for you better,
although a 2-dimensional array may be more convenient to use.
If you want to construct a BufferedImage object, you can specify it to be
1-bit per pixel type (see below), and fill its content using the setRGB() method.
Such image can then be saved to file or shown in GUI, or accessed with getRGB() method.
Here is a working example (GenerateChecker.java):
import java.awt.image.BufferedImage;
import javax.imageio.ImageIO;
import java.io.IOException;
import java.io.File;
public class GenerateChecker
{
private static final int width = 32;
private static final int height = 32;
public static void main(String args[]) throws IOException
{
BufferedImage im = new BufferedImage(32, 32, BufferedImage.TYPE_BYTE_BINARY);
int white = (255 << 16) | (255 << 8) | 255;
int black = 0;
for (int y = 0; y < height; y++)
for (int x = 0; x < width; x++)
im.setRGB(x, y, (((x + y)&1) == 0) ? black : white);
File outputfile = new File("checker.png");
ImageIO.write(im, "png", outputfile);
}
}
~
Related
I have to write a program in Java that uses StdAudio and Picture to create a two-dimensional color visualization of a sound file while it is playing but I'm not really sure how to.
Can someone tell me everything that I need or tell me what I need to do to "convert" the sound file so that it's readable by Picture?
I could grab the samples from the sound file and return them as array of doubles, but then how would that even create an image? How could those values even sync with the image?
I have been playing around in eclipse just trying to figure out how this could possibly even work but my code just ends up being a whole mess.
private final static int SAMPLE_RATE = 44100;
private static int WIDTH = 500;
private static int HEIGHT = 100;
private static JFrame frame;
private static Picture pic;
public static void main(String[] args) throws IOException
{
pic = new Picture(WIDTH, HEIGHT); // <- blank black image
String audioFile = "SampleTest2.wav";
double[] audio = StdAudio.read(audioFile);
frame = new JFrame();
frame.setContentPane(pic.getJLabel());
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.setTitle("Sound Visualization");
frame.setResizable(false);
frame.pack();
frame.setVisible(true);
for (int k = 0; k < audio.length; k++)
StdAudio.play(audio[k]);
for (int i = 0; i < pic.width(); i ++)
{
for (int j = 0; j < pic.height(); j++)
{
pic.set(i, j, toColor(audio[SAMPLE_RATE + i]));
//frame.setContentPane(pic.getJLabel());
}
frame.repaint();
}
}
private static Color toColor(double colVal)
{
int r = (int) (((colVal + 1) / 2) * 255);
int g = (int) (((colVal + 1) / 2) * 255);
int b = (int) (((colVal + 1) / 2) * 255);
return new Color(r, g, b);
}
To use StdAudio you need wav file with sampling rate of 44100. It means every second of this sound consists of 44100 values(samples). When you load such file with duration of 1 second using method double[] read(String filename) you will obtain an array with 44100 elements. Javadoc of that method tells us the values will be between -1.0 and +1.0. We can iterate over every sample, map values from -1..1 range to 0..255 range (because colors need values from 0 to 255) and paint each pixel with this color. For better effect let's not paint single pixel but a column of 100 pixels.
I'll create image of 500x100. It will display only 500 samples so it will represent 500/44100 = only 0,01 of a second. To create empty picture of that size use:
Picture p = new Picture(500, 100);
To paint separate pixels along the image use:
for (int i = 0; i < 500; i++) {
p.set(i, 0, color);
}
and to display this picture use:
p.show();
Next, to create a color we need 3 values: red, green and blue components. Here we have only one value so the resulting image will be a greyscale image because saturation of every component will be the same value new Color(value, value, value). To quickly convert a range from -1..1 to 0..255 use such formula: (int) (((d + 1) / 2) * 255)
I used the first sound file from this site:
http://www.music.helsinki.fi/tmt/opetus/uusmedia/esim/index-e.html and the image I obtained is:
The code I used is:
import java.awt.Color;
import java.io.IOException;
public class StackOverflow58899141 {
private static int IMAGE_WIDTH = 500;
private static int IMAGE_HEIGHT = 100;
static String filename = "O:\\1.wav";
public static void main(final String[] args) throws IOException {
// reading sound file to samples
double[] samples = StdAudio.read(filename);
// creating empty image
Picture p = new Picture(IMAGE_WIDTH, IMAGE_HEIGHT);
// filling image from left to right
for (int i = 0; i < IMAGE_WIDTH; i++) {
// filling image from top to bottom
for (int j = 0; j < IMAGE_HEIGHT; j++) {
// adding 44100 to skip 1s of silence at the beginning
p.set(i, j, doubleToColor(samples[44100 + i]));
}
}
p.show();
}
// convert number from range -1.0..1.0 to 0..255
private static Color doubleToColor(double d) {
int val = (int) (((d + 1) / 2) * 255);
return new Color(val, val, val);
}
}
Now you have a solid start to understand how it works. Although Picture class allows easy saving of an image it doesn't allow animating. To achieve that you'd need to create own JFrame and draw image and delay drawing each column of pixels to get the animation effect.
So today I started with a new project. I want to make a simple heightmap generator in java, so I tried the following:
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
public class Heightmap {
public static int width = 200;
public static int height = 200;
public static void main(String[] args) {
BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_BYTE_GRAY );
for(int x = 0; x < width; x++){
for(int y = 0; y < height; y++){
bufferedImage.setRGB(x, y, (byte )(Math.random() * 256 + 128) ); // + 128 because byte goes from -128 to 127
}
}
File outputFile = new File("heightmap.png");
try {
ImageIO.write(bufferedImage, "png", outputFile);
}catch (IOException ioex){
ioex.printStackTrace();
}
}
}
The code is very simple, I plan to try perlin noise as the next step. But first I need to resolve this problem:
Generated Heightmap
The pixels in heightmap.png are either completely white, or completely black. There's no grays in the image, which of course is necessary in a heightmap. Does anyone know what I did wrong?
is it the BufferedImage.TYPE_BYTE_GRAY part? If so, what should I use instead?
After a friend set me on the right track, I found the solution.
Instead of BufferedImage.TYPE_BYTE_GRAY I used BufferdImage.TYPE_INT_RGB. So this is indeed where I went wrong. Also I added the object Color randomColor, wherein the RGB values all share the same integer with a value from 0 to 255. Then in BufferedImage.setRGB I use the color code of randomColor (so R,G,B = 255 gives #FFFFFF, which is white) as the value of pixel (x,y):
import java.awt.Color;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
public class Heightmap {
public static int width = 200;
public static int height = 200;
public static void main(String[] args) {
BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB );
for(int x = 0; x < width; x++){
for(int y = 0; y < height; y++){
int randomValue = (int)(Math.random() * 256);
Color randomColor = new Color( randomValue, randomValue, randomValue);
bufferedImage.setRGB(x, y, randomColor.getRGB());
}
}
File outputFile = new File("heightmap.png");
try {
ImageIO.write(bufferedImage, "png", outputFile);
}catch (IOException ioex){
ioex.printStackTrace();
}
}
}
Now the heightmap.png gives what I expected: Heightmap.png
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()) ;
}
I am trying to get every single color of every single pixel of an image.
My idea was following:
int[] pixels;
BufferedImage image;
image = ImageIO.read(this.getClass.getResources("image.png");
int[] pixels = ((DataBufferInt)image.getRaster().getDataBuffer()).getData();
Is that right? I can't even check what the "pixels" array contains, because i get following error:
java.awt.image.DataBufferByte cannot be cast to java.awt.image.DataBufferInt
I just would like to receive the color of every pixel in an array, how do i achieve that?
import java.io.*;
import java.awt.*;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
public class GetPixelColor {
public static void main(String args[]) throws IOException {
File file = new File("your_file.jpg");
BufferedImage image = ImageIO.read(file);
// Getting pixel color by position x and y
int clr = image.getRGB(x, y);
int red = (clr & 0x00ff0000) >> 16;
int green = (clr & 0x0000ff00) >> 8;
int blue = clr & 0x000000ff;
System.out.println("Red Color value = " + red);
System.out.println("Green Color value = " + green);
System.out.println("Blue Color value = " + blue);
}
}
of course you have to add a for loop for all pixels
The problem (also with the answer that was linked from the first answer) is that you hardly ever know what exact type your buffered image will be after reading it with ImageIO. It could contain a DataBufferByte or a DataBufferInt. You may deduce it in some cases via BufferedImage#getType(), but in the worst case, it has type TYPE_CUSTOM, and then you can only fall back to some instanceof tests.
However, you can convert your image into a BufferedImage that is guaranteed to have a DataBufferInt with ARGB values - namely with something like
public static BufferedImage convertToARGB(BufferedImage image)
{
BufferedImage newImage = new BufferedImage(
image.getWidth(), image.getHeight(),
BufferedImage.TYPE_INT_ARGB);
Graphics2D g = newImage.createGraphics();
g.drawImage(image, 0, 0, null);
g.dispose();
return newImage;
}
Otherwise, you can call image.getRGB(x,y), which may perform the required conversions on the fly.
BTW: Note that obtaining the data buffer of a BufferedImage may degrade painting performance, because the image can no longer be "managed" and kept in VRAM internally.
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
public class Main {
public static void main(String[] args) throws IOException {
BufferedImage bufferedImage = ImageIO.read(new File("norris.jpg"));
int height = bufferedImage.getHeight(), width = bufferedImage.getWidth();
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
int RGBA = bufferedImage.getRGB(x, y);
int alpha = (RGBA >> 24) & 255;
int red = (RGBA >> 16) & 255;
int green = (RGBA >> 8) & 255;
int blue = RGBA & 255;
}
}
}
}
Assume the buffered image represents an image with 8-bit RGBA color components packed into integer pixels, I search for "RGBA color space" on wikipedia and found following:
In the byte-order scheme, "RGBA" is understood to mean a byte R,
followed by a byte G, followed by a byte B, and followed by a byte A.
This scheme is commonly used for describing file formats or network
protocols, which are both byte-oriented.
With simple Bitwise and Bitshift you can get the value of each color and the alpha value of the pixel.
Very interesting is also the other order scheme of RGBA:
In the word-order scheme, "RGBA" is understood to represent a complete
32-bit word, where R is more significant than G, which is more
significant than B, which is more significant than A. This scheme can
be used to describe the memory layout on a particular system. Its
meaning varies depending on the endianness of the system.
byte[] pixels
not
int[] pixels
try this : Java - get pixel array from image
import java.awt.Color;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
public class ImageUtil {
public static Color[][] loadPixelsFromImage(File file) throws IOException {
BufferedImage image = ImageIO.read(file);
Color[][] colors = new Color[image.getWidth()][image.getHeight()];
for (int x = 0; x < image.getWidth(); x++) {
for (int y = 0; y < image.getHeight(); y++) {
colors[x][y] = new Color(image.getRGB(x, y));
}
}
return colors;
}
public static void main(String[] args) throws IOException {
Color[][] colors = loadPixelsFromImage(new File("image.png"));
System.out.println("Color[0][0] = " + colors[0][0]);
}
}
I know this has already been answered, but the answers given are a bit convoluted and could use improvement.
The simple idea is to just loop through every (x,y) pixel in the image, and get the color of that pixel.
BufferedImage image = MyImageLoader.getSomeImage();
for ( int x = 0; x < image.getWidth(); x++ ) {
for( int y = 0; y < image.getHeight(); y++ ) {
Color pixel = new Color( image.getRGB( x, y ) );
// Do something with pixel color here :)
}
}
You could then perhaps wrap this method in a class, and implement Java's Iterable API.
class IterableImage implements Iterable<Color> {
private BufferedImage image;
public IterableImage( BufferedImage image ) {
this.image = image;
}
#Override
public Iterator<Color> iterator() {
return new Itr();
}
private final class Itr implements Iterator<Color> {
private int x = 0, y = 0;
#Override
public boolean hasNext() {
return x < image.getWidth && y < image.getHeight();
}
#Override
public Color next() {
x += 1;
if ( x >= image.getWidth() ) {
x = 0;
y += 1;
}
return new Color( image.getRGB( x, y ) );
}
}
}
The usage of which might look something like the following
BufferedImage image = MyImageLoader.getSomeImage();
for ( Color color : new IterableImage( image ) ) {
// Do something with color here :)
}
im using the imageJ library to read a .tiff image file. But when im trying to read the pixels of image1 in variable c, i get an error saying "incompatible types: required int, found int[].
im quiet new to java, so can somebody tell me how to get around this problem. The code is otherwise working fine with other image formats.
import java.awt.Color;
import java.awt.image.BufferedImage;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import javax.imageio.ImageIO;
import ij.ImagePlus;
public class GetPixelCoordinates {
//int y, x, tofind, col;
/**
* #param args the command line arguments
* #throws IOException
*/
public static void main(String args[]) throws IOException {
try {
//read image file
ImagePlus img = new ImagePlus("E:\\abc.tiff");
//write file
FileWriter fstream = new FileWriter("E:\\log.txt");
BufferedWriter out = new BufferedWriter(fstream);
//find cyan pixels
for (int y = 0; y < img.getHeight(); y++) {
for (int x = 0; x < image.getWidth(); x++) {
int c = img.getPixel(x,y);
Color color = new Color(c);
if (color.getRed() < 30 && color.getGreen() >= 225 && color.getBlue() >= 225) {
out.write("CyanPixel found at=" + x + "," + y);
out.newLine();
}
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
If you look at the documentation for getPixel(int,int) in ImagePlus you'll see that it returns an array of ints rather than a single int:
Returns the pixel value at (x,y) as a 4 element array. Grayscale values are retuned in the first element. RGB values are returned in the first 3 elements. For indexed color images, the RGB values are returned in the first 3 three elements and the index (0-255) is returned in the last.
It looks as if you're dealing with an RGB image, so you should be able to do the following instead:
int [] colorArray = image1.getPixel(x,y);
int redValue = colorArray[0];
int greenValue = colorArray[1];
int blueValue = colorArray[2];