Given an image that is in grayscale, how would I get the pixel values of the grayscale at that location?
This outputs temp as -16777216 (black) all the time.
public void testMethod()
{
int width = imgMazeImage.getWidth();
int height = imgMazeImage.getHeight();
//Assign class variable as a new image with RGB formatting
imgMazeImage = new BufferedImage(width, height, BufferedImage.TYPE_BYTE_GRAY);
for(int i=0; i < width; i ++){
for(int j=0; j < height; j++)
{
//Grab and set the colors one-by-one
inttemp = imgMazeImage.getRGB(j, i);
System.out.println(temp);
}
}
}
you are creating a new blank image and assigning it to your class variable:
imgMazeImage = new BufferedImage(width, height, BufferedImage.TYPE_BYTE_GRAY);
the pixels are created with a default value and its logical that they all have the same color (black) at the stage when you are printing them since you did not manipulate the color in any pixel yet.
also, your code might fail if the width is not equal to the height. according to your for loops, i runs along width and j runs along height. therefore, you should change
int temp = imgMazeImage.getRGB(j, i);
to
int temp = imgMazeImage.getRGB(i, j);
Related
I have a Bufferedimage that is 1px high and eg wide. I need to create another Bufferedimage that will be in 1:1 resolution. I know what can be done in this case by calculating the square root of the width, but what if the result is not an integer? I have a method for creating a matrix (a list of each pixel in turn) from the width and height, so there will be no problems. At the end, if there are empty pixels, I can make them transparent, so not necessarily a completely filled square. I just need to get the dimensions of the square, having the width of the original photo, I will fill in the pixels myself.
my code:
public static BufferedImage encode(String str){
byte[] bytes = str.getBytes();
BufferedImage img = new BufferedImage(bytes.length, 1, BufferedImage.TYPE_INT_ARGB);
for (int i = 0; i < bytes.length; i++) {
img.setRGB(i, 0,encode(bytes[i]).getRGB() );
}
return img;
}
public static Color encode(byte byt){
return new Color(byt+128,byt+128,byt+128);
}
public static BufferedImage encode(String str){
byte[] bytes = str.getBytes();
int w = bytes.length;
int width = (int) Math.ceil(Math.sqrt(w));
BufferedImage img = new BufferedImage(width, width, BufferedImage.TYPE_INT_ARGB);
for (int index = 0; index < bytes.length; index++) {
img.setRGB(index%width, (int)Math.floor(index/(float)width),encode(bytes[index]).getRGB() );
}
return img;
}
code update. I just calculate the square root, and if the number is not an integer, then I round up to a larger one and as a result I get the height of the image, because the image has a 1:1 format, we immediately got the width. Then I just fill in the formula:
x = byteIndex % imageWidth
y = floor(byteIndex / imageHeight)
I am new to programming and I'm currently working on a program that rotates an image to the right and upside down. I was able to get the upside down method working but not the rotate to the right (90 degrees clockwise). It keeps giving me an out of bounds error, and I'm not sure why as I have looked at other examples. Any help would be appreciated.
Here's is the method that I'm working on:
public Image rotateRight()
{
Image right = new Image (this);
img = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
int width = right.img.getWidth();
int height = right.img.getHeight();
for (int i = 0; i < width; i++)
for (int j = 0; j < height; j++)
{
this.img.setRGB(height-j-1,i,right.img.getRGB(i,j));
}
return right;
}
Here's the rest of the code:
import java.awt.image.*;
import java.io.*;
import javax.imageio.*;
public class Image {
private BufferedImage img = null;
int width;
int height;
private Image()
{
}
public Image (int w, int h)
{
img = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB );
width = w;
height = h;
}
public Image (Image anotherImg)
{
width = anotherImg.img.getWidth();
height = anotherImg.img.getHeight();
img = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB );
for (int i = 0; i < height; i++)
for (int j = 0; j < width; j++)
{
this.img.setRGB(j,i,anotherImg.img.getRGB(j,i)) ;
}
}
public String toString()
{
return "Width of Image:" +width+"\nHeight of Image:"+height;
}
public Image (String filename)
{
try
{
img = ImageIO.read(new File(filename));
width = img.getWidth();
height = img.getHeight();
}
catch (IOException e)
{
System.out.println(e);
}
}
public void save(String filename, String extension)
{
try
{
File outputfile = new File(filename);
ImageIO.write(img, extension, outputfile);
}
catch (IOException e)
{
System.out.println(e);
}
}
public Image copy()
{
Image copiedImage = new Image(this);
return copiedImage;
}
Here's Main:
public static void main (String args[])
{
Image srcimg = new Image("apple.jpg");
System.out.println(srcimg);
Image copy = srcimg.copy();
copy.save("apple-copy.jpg", "jpg");
Image copy2 = srcimg.copy();
Image right = copy2.rotateRight();
right.save("apple-rotateRight.jpg", "jpg");
}
The reason you are getting an ArrayIndexOutOfBoundsException when rotating your image is as stated. Something is out of bounds. It could be either your i variable that has exceeded its bounds or your j variable that has exceeded its bounds and this is generally easy to test for by just adding a print statement within your for loop and checking which one of the two values is out of bounds. It is good practice to try to resolve these problems yourself as you will start learning what causes these and where the problem lies.
Anyways enough of my rambling. The problem that you seem to have is that you are trying to turn the image without changing the size of the image.
You are creating a new Image with the same width and height parameters as the original
img = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB );
However when you want to rotate an image by 90 degrees you actually want to flip the width and height parameters. If you think about it, it makes sense when you rotate an image by 90 degrees the width will become the height and the height will become the width.
So your problem is here:
this.img.setRGB(height-j-1,i,right.img.getRGB(i,j));
In your case the bounds for the x parameter in the setRGB function is from 0 to the WIDTH of your image and the y parameter is from 0 to the HEIGHT of your image. Therefore because your height variable is different from your width. If for example your WIDTH is 200 and your HEIGHT is 100. When you put this in to the function the greatest value for the x parameter will be:
'100 - 199 - 1 = -100' which is clearly out of bounds. However if we change your code to.
img = new BufferedImage(height, width, BufferedImage.TYPE_INT_RGB );
now when we do the same thing as before where we get the maximum possible value.
WIDTH = 100, HEIGHT = 200;
'200 - 99 - 1 = 100' which is inside the bounds
As we read a RGB image , do the shifting operations to get the R, G and B matrices separately ...Is it possible to read a gray scale image(JPEG) and directly manipulate its pixel values.And then rewrite the image ?
Ultimately I have to do the DCT operation on the gray scale image.
The code below will read the grayscale image to simple two dimensional array:
File file = new File("path/to/file");
BufferedImage img = ImageIO.read(file);
int width = img.getWidth();
int height = img.getHeight();
int[][] imgArr = new int[width][height];
Raster raster = img.getData();
for (int i = 0; i < width; i++) {
for (int j = 0; j < height; j++) {
imgArr[i][j] = raster.getSample(i, j, 0);
}
}
Note: The raster.getSample(...) method takes 3 arguments: x - the X coordinate of the pixel location, y - the Y coordinate of the pixel location, b - the band to return. In case of the grayscale images we should/may get only the 0 band.
We are trying to get only the portion of the image out of the captured image. But in java we only get subimage in rectangular form using image.getImage(x,y,width, height). Let say if i virutally split the image as 10 parts as shown below. How can i able to extract only 1,2,4,6,8,9,10 out of it as show in the second image using native java very without consuming too many resources and time.
Update
Below is the sample code
for (int x = 0; x < columns; x++) {
for (int y = 0; y < rows; y++) {
imagePart = img.getSubimage(x * this.smallWidth, y
* this.smallHeight, this.smallWidth,
this.smallHeight);
if (!ifSelectedPart(imagePart)) {
smallImages[x][y] = imagePart;
}
else {
smallImages[x][y] = fillwithAlpha();
}
}
createImage(smallImages[][])
If these rectangles are all the same size you can treat the image as a grid and calculate what region of the image you need with a little math.
int numberColumns = 2;
int numberRows = 5;
public Rectangle getSubregion(int row, int column, int imgWidth, int imgHeight){
int cellWidth = imgWidth / numberColumns;
int cellHeight = imgHeight / numberRows;
return new Rectangle(column*cellWidth, row*cellHeight,cellWidth, cellHeight);
}
//usage
Rectangle cellOne = getSubregion(0, 0, img.getWidth(),img.getHeight());
Then just render each of those subregions to a new image in memory.
Images are by their nature rectangular. Perhaps you wish to draw over the image with 0 alpha composite color to cover up the region that you don't want to see. Either that or create a grid of rectangular sub-images, and keep the ones from the grid that you want to display.
I am working with a LayeredPane that contains two images, one on each layer. I have been working on a method that obtains the image positions (based on the label positions the images are in) and then save the bottom image (lower one from within the layeredPane) and also the top one if it is at all covering the bottom image (may only be a part of the image), however I have been having some trouble with this and I'm a bit unsure on how to get it working properly.
I have been stuck working on this for quite a while now so any help with my existing code or thoughts on how I should approach this another way would be a big help for me.
Thanks in advance.
public void saveImageLayering(BufferedImage topImg,BufferedImage bottomImg, JLabel topLabel, JLabel bottomLabel) {
int width = bottomImg.getWidth();
int height = bottomImg.getHeight();
Point bottomPoint = new Point();
Point topPoint = new Point();
bottomPoint = bottomLabel.getLocation();
topPoint = topLabel.getLocation();
System.out.println("image x coordinate " + bottomPoint.x);
System.out.println("image y coordinate " + bottomPoint.y);
//arrays to store the bottom image
int bottomRedImgArray[][] = new int[width][height];
int bottomGreenImgArray[][] = new int[width][height];
int bottomBlueImgArray[][] = new int[width][height];
//arrays to store the top image
int topRedImgArray[][] = new int[width][height];
int topGreenImgArray[][] = new int[width][height];
int topBlueImgArray[][] = new int[width][height];
//loop through the bottom image and get all pixels rgb values
for(int i = bottomPoint.x; i < width; i++){
for(int j = bottomPoint.y; j < height; j++){
//set pixel equal to the RGB value of the pixel being looked at
pixel = new Color(bottomImg.getRGB(i, j));
//contain the RGB values in the respective RGB arrays
bottomRedImgArray[i][j] = pixel.getRed();
bottomGreenImgArray[i][j] = pixel.getGreen();
bottomBlueImgArray[i][j] = pixel.getBlue();
}
}
//create new image the same size as old
BufferedImage newBottomImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
//set values within the 2d array to the new image
for (int x1 = 0; x1 < width; x1++){
for (int y1 = 0; y1 < height; y1++){
//putting values back into buffered image
int newPixel = (int) bottomRedImgArray[x1][y1];
newPixel = (newPixel << 8) + (int) bottomGreenImgArray[x1][y1];
newPixel = (newPixel << 8) + (int) bottomBlueImgArray[x1][y1];
newBottomImage.setRGB(x1, y1, newPixel);
}
}
//create rectangle around bottom image to check if coordinates of top in inside and save only the ones that are
Rectangle rec = new Rectangle(bottomPoint.x, bottomPoint.y, bottomImg.getWidth(), bottomImg.getHeight());
//loop through the top image and get all pixels rgb values
for(int i = bottomPoint.x; i < bottomImg.getWidth(); i++){
for(int j = bottomPoint.y; j < bottomImg.getHeight(); j++){
//if top image is inside lower image then getRGB values
if (rec.contains(topPoint)) { //___________________________________________________________doesnt contain any..
if (firstPointFound == true) {
//set pixel equal to the RGB value of the pixel being looked at
pixel = new Color(topImg.getRGB(i, j));
//contain the RGB values in the respective RGB arrays
topRedImgArray[i][j] = pixel.getRed();
topGreenImgArray[i][j] = pixel.getGreen();
topBlueImgArray[i][j] = pixel.getBlue();
} else {
firstPoint = new Point(i, j);
firstPointFound = true;
}
}
}
}
//create new image the same size as old
BufferedImage newTopImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
//set values within the 2d array to the new image
for (int x1 = 0; x1 < topImg.getWidth(); x1++){
for (int y1 = 0; y1 < topImg.getHeight(); y1++){
//putting values back into buffered image
int newPixel = (int) topRedImgArray[x1][y1];
newPixel = (newPixel << 8) + (int) topGreenImgArray[x1][y1];
newPixel = (newPixel << 8) + (int) topBlueImgArray[x1][y1];
newTopImage.setRGB(x1, y1, newPixel);
}
}
BufferedImage newImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
//uses the Graphics.drawImage() to place them on top of each other
Graphics g = newImage.getGraphics();
g.drawImage(newBottomImage, bottomPoint.x, bottomPoint.y, null);
g.drawImage(newTopImage, firstPoint.x, firstPoint.y, null);
try {
//then save as image once all in correct order
File outputfile = new File("saved_Layered_Image.png");
ImageIO.write(newImage, "png", outputfile);
JOptionPane.showMessageDialog(null, "New image saved successfully");
} catch (IOException e) {
e.printStackTrace();
}
}
I'm not really sure why you're messing around with the pixels, however, the idea is relatively simple
Basically, you want to create a third "merged" image which is the same size as the bottomImage. From there, you simply want to paint the bottomImage onto the merged image at 0x0.
Then you need to calculate the distance that the topImage is away from bottomImage's location and paint it at that point.
BufferedImage merged = new BufferedImage(bottomImg.getWidth(), bottomImg.getHeight(), BufferedImage.TYPE_INT_ARGB);
Graphics2D g2d = master.createGraphics();
g2d.drawImage(bottomImg, 0, 0, this);
int x = topPoint .x - bottomPoint .x;
int y = topPoint .y - bottomPoint .y;
g2d.drawImage(topImg, x, y, this);
g2d.dispose();
Using this basic idea, I was able to produce these...