I have been given an assignment where I have to read two images from secondary memory and I have to store them in two separate matrices. Then I have to multiply these matrices and convert the resultant matrix back to an image and store it in the HDD. Here is the code:
package ISI;
import java.io.*;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.awt.image.PixelGrabber;
import javax.imageio.ImageIO;
import javax.swing.*;
class ImageMultiplication {
BufferedImage img1, img2;
File f1, f2;
int matrix1[][], matrix2[][], matrix3[][];
int w,h;
ImageMultiplication() {
img1 = img2 = null;
f1 = f2 = null;
w = 500;
h = 400;
}
void readImages() throws IOException {
f1 = new File("image1.jpg");
f2 = new File("image2.jpg");
img1 = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
img2 = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
img1 = ImageIO.read(f1);
img2 = ImageIO.read(f2);
System.out.println("\nReading of images complete");
}
void convertToMatrix() {
int [] array1 = new int[w*h];
matrix1 = new int[h][w];
int [] array2 = new int[w*h];
matrix2 = new int[w][h];
matrix3 = new int[h][h];
try {
img1.getRGB(0, 0, w, h, array1, 0, w);
img2.getRGB(0, 0, w, h, array2, 0, w);
}
catch(Exception e) {
System.out.println("\nInterrupted");
}
int count=0;
for(int i=0;i<h;i++) {
for(int j=0;j<w;j++) {
if(count == array1.length)
break;
matrix1[i][j] = array1[count];
count++;
}
}
count=0;
for(int i=0;i<w;i++) {
for(int j=0;j<h;j++) {
if(count == array2.length)
break;
matrix2[i][j]=array2[count];
count++;
}
}
int sum = 0, c, d, k;
for (c = 0; c < h; c++) {
for (d = 0; d < h; d++) {
for (k = 0; k < w; k++)
sum = sum + matrix1[c][k] * matrix2[k][d];
matrix3[c][d] = sum;
sum = 0;
}
}
/* Comment snippet 1
for(int i = 0; i<h; i++) {
for(int j = 0; j<h; j++)
System.out.print(" "+matrix3[i][j]);
System.out.println();
}
*/
}
void convertMatrixToImage() {
BufferedImage image = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
try {
for(int i=0; i<h; i++) {
for(int j=0; j<h; j++) {
int a = matrix3[i][j];
Color newColor = new Color(a,a,a);
image.setRGB(j,i,newColor.getRGB());
}
}
ImageIO.write(image, "jpg", new File("Output.jpg"));
}
catch(Exception e) {}
System.out.println(image.toString());
System.out.println("\nThe output image has been generated!");
}
public static void main(String [] args) throws IOException {
ImageMultiplication i = new ImageMultiplication();
i.readImages();
i.convertToMatrix();
i.convertMatrixToImage();
}
}
The file executes with no problem.
See
The problem is, However, that no image file is created or written in the directory ( void convertMatrixToImage() ). If I uncomment (comment snippet 1), I get a 2D matrix as the output on the console window where each index shows a numeric value which I am assuming to be the pixed RGB value. But there is no sign whatsoever of any image file ever being created. Can somebody please help me out?
Note: I have tried converting the array to byte array and then writing the image file and I have tried other methods as well, but nothing seems to work. I tried it even on Windows but it also has the same problem. Nowhere is the Output.jpg being created/written.
When I run your, modified code to print the Exception, I get...
java.lang.IllegalArgumentException: Color parameter outside of expected range: Red Green Blue
at java.awt.Color.testColorValueRange(Color.java:310)
at java.awt.Color.<init>(Color.java:395)
at java.awt.Color.<init>(Color.java:369)
at javaapplication194.ImageMultiplication.convertMatrixToImage(JavaApplication194.java:102)
at javaapplication194.ImageMultiplication.main(JavaApplication194.java:118)
Now, I'll be honest, I had no idea what this "really" means, but I know it has something to do with "color"
So I had a look back over the conversation code...
try {
for (int i = 0; i < h; i++) {
for (int j = 0; j < h; j++) {
int a = matrix3[i][j];
Color newColor = new Color(a, a, a);
image.setRGB(j, i, newColor.getRGB());
}
}
ImageIO.write(image, "jpg", new File("Output.jpg"));
} catch (Exception e) {
e.printStackTrace();
}
And noted...
int a = matrix3[i][j];
Color newColor = new Color(a, a, a);
image.setRGB(j, i, newColor.getRGB());
This seems very weird to me for a number of reasons...
You use getRGB to get the color as a packed int value
You try and make a new color from this packed int
You use getRGB to return a packed int from a color based on a packed int
All of which seems, wrong and unnecessary, you already have a packed int RGB value, why not just use
int a = matrix3[i][j];
//Color newColor = new Color(a, a, a);
image.setRGB(j, i, a);
adding this, the error goes away and the image is created
Related
When I give it a picture with salt and pepper noise it returns an image loosing all details and I don't know what's wrong with my code:
public class Q1 {
public static void main(String[] args) throws IOException {
BufferedImage img = ImageIO.read(new File("task1input.png"));
//get dimensions
int maxHeight = img.getHeight();
int maxWidth = img.getWidth();
//create 2D Array for new picture
int pictureFile[][] = new int [maxHeight][maxWidth];
for( int i = 0; i < maxHeight; i++ ){
for( int j = 0; j < maxWidth; j++ ){
pictureFile[i][j] = img.getRGB( j, i );
}
}
int output [][] = new int [maxHeight][maxWidth];
//Apply Mean Filter
for (int v=1; v<maxHeight; v++) {
for (int u=1; u<maxWidth; u++) {
//compute filter result for position (u,v)
int sum = 0;
for (int j=-1; j<=1; j++) {
for (int i=-1; i<=1; i++) {
if((u+(j)>=0 && v+(i)>=0 && u+(j)<maxWidth && v+(i)<maxHeight)){
int p = pictureFile[v+(i)][u+(j)];
sum = sum + p;
}
}
}
int q = (int) (sum /9);
output[v][u] = q;
}
}
//Turn the 2D array back into an image
BufferedImage theImage = new BufferedImage(
maxHeight,
maxWidth,
BufferedImage.TYPE_INT_RGB);
int value;
for(int y = 1; y<maxHeight; y++){
for(int x = 1; x<maxWidth; x++){
value = output[y][x] ;
theImage.setRGB(y, x, value);
}
}
File outputfile = new File("task1output3x3.png");
ImageIO.write(theImage, "png", outputfile);
}
}
getRGB "Returns an integer pixel in the default RGB color model (TYPE_INT_ARGB)" so therefore you have to extract the R, G, and B and add them separately; then put them back together. One way is this
int pixel=pictureFile[u+i][v+j];
int rr=(pixel&0x00ff0000)>>16, rg=(pixel&0x0000ff00)>>8, rb=pixel&0x000000ff;
sumr+=rr;
sumg+=rg;
sumb+=rb;
then to put them back together
sumr/=9; sumg/=9; sumb/=9;
newPixel=0xff000000|(sumr<<16)|(sumg<<8)|sumb);
I am learn Image Processing Techniques and have some homework.
In my homework, which asked me to cover a RBG to gray image.
I've converted the images into 2D matrix, do somethings, and when i cover again from 2D matrix to image, some wrong happen.
This my code:
private static SampleModel samM;
public static int[][] imageToArrayPixel(File file) {
try {
BufferedImage img = ImageIO.read(file);
Raster raster = img.getData();
int w = raster.getWidth(), h = raster.getHeight();
int pixels[][] = new int[w][h];
for (int x = 0; x < w; x++) {
for (int y = 0; y < h; y++) {
pixels[x][y] = raster.getSample(x, y, 0);
System.out.print(" " + pixels[x][y]);
}
System.out.println("");
}
samM = raster.getSampleModel();
return pixels;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
public static java.awt.Image getImage(int pixels[][]) {
int w = pixels.length;
int h = pixels[0].length;
WritableRaster raster = Raster.createWritableRaster(samM, new Point(0, 0));
for (int i = 0; i < w; i++) {
for (int j = 0; j < pixels[i].length; j++) {
if (pixels[i][j] > 128) {
raster.setSample(i, j, 1, 255);
} else {
raster.setSample(i, j, 1, 0);
}
}
}
BufferedImage image = new BufferedImage(w, h, BufferedImage.TYPE_BYTE_GRAY);
image.setData(raster);
File output = new File("check.jpg");
try {
ImageIO.write(image, "jpg", output);
} catch (Exception e) {
e.printStackTrace();
}
return image;
}
public static java.awt.Image getImageWithRBG(Pixel pixels[][]) {
int w = pixels.length;
int h = pixels[0].length;
WritableRaster raster = Raster.createWritableRaster(samM, new Point(0, 0));
int[] pixelValue = new int[3];
for (int i = 0; i < w; i++) {
for (int j = 0; j < h; j++) {
pixelValue[0] = pixels[i][j].red;
pixelValue[1] = pixels[i][j].blue;
pixelValue[2] = pixels[i][j].green;
raster.setPixel(j, i, pixelValue);
}
}
BufferedImage image = new BufferedImage(h, w, BufferedImage.TYPE_CUSTOM);
image.setData(raster);
File output = new File("check.jpg");
try {
ImageIO.write(image, "jpg", output);
} catch (Exception e) {
e.printStackTrace();
}
return image;
}
public static void main(String[] args) throws IOException {
int pixel[][] = imageToArrayPixel(new File("C:\\Users\\KimEricko\\Pictures\\1402373904964_500.jpg"));
getImage(pixel);
}
This my image which i use to covert:
before
and here is the photo that I received after restoration:
after
I don't understand why the picture after restoring contains only 1/3 of the original photograph.
What can I do to fix this?
looks to me like there is a bug in getImageWithRBG, that
raster.setPixel(j, i, pixelValue);
should be
raster.setPixel(i, j, pixelValue);
setPixel and setSample have similar inputs: x then y
I don't know if there are other problems, that is just the first thing I noticed.
I have several methods that manipulate a .jpg image: mirroring on x and y axis, tiling it, converting to ASCII text, and adjusting its brightness. All the methods work properly except the brightness one. When I run the brightness method, there is a NullPointerException in readGrayscaleImage() (see below - instructor written code). The BufferedImage is null, however it isn't when the method is called from any other of my methods (mirrors, tiling, ascii all read the file correctly). Not only is the BufferedImage null, the input image it is trying to read gets overwritten with 0 bytes and cannot be viewed in an image viewer, which would probably explain why the BufferedImage is null.
Here is a working method that calls readGrayscaleImage():
public static void tileImage(int h, int v, String infile, String outfile) {
int[][] result = readGrayscaleImage(infile);
int[][] tileResult = new int[result.length * h][result[0].length * v];
for (int hh = 0; hh < h; hh++) {
for (int vv = 0; vv < v; vv++) {
for (int i = 0; i < result.length; i++) {
for (int j = 0; j < result[i].length; j++) {
tileResult[i + hh * result.length][j + vv * result[i].length] = result[i][j];
}
}
}
}
writeGrayscaleImage(outfile, tileResult);
}
Here is the brightness method that results in the problem:
public static void adjustBrightness(int amount, String infile, String outfile) {
int[][] result = readGrayscaleImage(infile); // NullPointerException trace points here
for (int i = 0; i < result.length; i++) {
for (int j = 0; j < result[i].length; j++) {
if (result[i][j] + amount > 255)
result[i][j] = 255;
else if (result[i][j] + amount < 0)
result[i][j] = 0;
else
result[i][j] += amount;
}
}
writeGrayscaleImage(outfile, result);
}
Here is the instructor-written code that reads a greyscale .jpg file and returns an array of integers:
public static int[][] readGrayscaleImage(String filename) {
int [][] result = null; //create the array
try {
File imageFile = new File(filename); //create the file
BufferedImage image = ImageIO.read(imageFile);
int height = image.getHeight(); // NullPointerException POINTS HERE - image IS NULL
int width = image.getWidth();
result = new int[height][width]; //read each pixel value
for (int x = 0; x < width; x++) {
for (int y = 0; y < height; y++) {
int rgb = image.getRGB(x, y);
result[y][x] = rgb & 0xff;
}
}
}
catch (Exception ioe) {
System.err.println("Problems reading file named " + filename);
ioe.printStackTrace();
System.exit(-1);
}
return result; //once we're done filling it, return the new array
}
Here is the instructor written method to write a .jpg:
public static void writeGrayscaleImage(String filename, int[][] array) {
int width = array[0].length;
int height = array.length;
try {
BufferedImage image = new BufferedImage(width, height,
BufferedImage.TYPE_INT_RGB); //create the image
//set all its pixel values based on values in the input array
for (int x = 0; x < width; x++) {
for (int y = 0; y < height; y++) {
int rgb = array[y][x];
rgb |= rgb << 8;
rgb |= rgb << 16;
image.setRGB(x, y, rgb);
}
}
//write the image to a file
File imageFile = new File(filename);
ImageIO.write(image, "jpg", imageFile);
}
catch (IOException ioe) {
System.err.println("Problems writing file named " + filename);
System.exit(-1);
}
}
(Wanted to comment but am not able to.)
BufferedImage image = ImageIO.read(filename);
Should this be
BufferedImage image = ImageIO.read(imageFile);
? I don't even see an override of read that takes a string.
public static void sample(BufferedImage image) {
int width = image.getWidth();
int height = image.getHeight();
int value[][] = new int[width][height];
int valueR[][] = new int[width][height];
int valueG[][] = new int[width][height];
int valueB[][] = new int[width][height];
for (int j = 0; j < height; j++) {
for (int i = 0; i < width; i++) {
int pixel = image.getRGB(i, j);
value[i][j] = pixel;
Color c = new Color(pixel);
valueR[i][j]= c.getRed();
valueG[i][j] = c.getGreen();
valueB[i][j] = c.getBlue();
System.out.println("Red value = "+valueR[i][j]);
System.out.println("Green value ="+valueG[i][j]);
System.out.println("Blue value"+valueB[i][j]);
}
}
}
The above code is to store RGB values and pixel color values of an image in an array separately.
public static BigInteger modPow(BigInteger a1, BigInteger e, BigInteger n) {
BigInteger r = 1;
for (int i = e.bitLength() - 1; i >= 0; i--) {
r = (r.multiply(r)).mod(n);
if (e.testBit(i)) {
r = (r.multiply(a1)).mod(n);
}
}
System.out.println("C value = " + r);
int lng = 3;
BigInteger bi = BigInteger.valueOf(lng);
BigInteger a = r.divide(bi);
BigInteger b = r.mod(bi);
System.out.println("pixel position a = " + a);
System.out.println("modulus value b = " + b);
return r;
}
In the above code am finding pixel position where i need to embed the secret bit.so i need to go to that specific pixel to embed the message.But in the previous code am storing pixel color in array value[][].i need to search through the array value[][] to get the pixel position which i got in last code.
Note: a1 is the position of current bit of information file to embed
{e,n} is public key
My question is how to find the pixel positions?
To find the position of a pixel is a simple concept with a complex execution. I've written some code here that takes a BufferedImage and searches through it for a pixel of a specific color.
import java.awt.Color;
import java.awt.image.BufferedImage;
import java.io.File;
import javax.imageio.ImageIO;
import java.io.IOException;
public class pixelSearch {
public static void main(String[] args) {
//I don't know where you're getting your image but i'll get one from file
File image = new File("image.bmp");
try {
BufferedImage imageToSearch = ImageIO.read(image);
Color colorToFind = new Color(255,255,255); //define color to search for with RGB vals 255,255,255
//for more information on constructing colors look here: http://docs.oracle.com/javase/7/docs/api/java/awt/Color.html
int[] pixelCoordinates = pSearch( colorToFind, imageToSearch ); //search for the pixel
System.out.println("Found pixel at (" + pixelCoordinates[0] + "," + pixelCoordinates[1] + ")."); //display coordinates
} catch (IOException e) {
System.out.println(e.toString());
}
}
private static int[] pSearch ( Color c, BufferedImage pic ){
int cVal = c.getRGB(); //get integer value of color we are trying to find
int x1 = 0;
int y1 = 0;
int x2 = pic.getWidth();
int y2 = pic.getHeight();
int[] XArray = new int[x2-x1+1]; //create an array to hold all X coordinates in image
int iterator = 0;
while (iterator <= x2) {
XArray[iterator] = x1 + iterator;
iterator++;
}
int [] YArray = new int[y2-y1+1]; //create an array to hold all Y coordinates in image
iterator = 0;
while (iterator <= y2) {
YArray[iterator] = y1 + iterator;
iterator++;
}
//next we iterate throug all the possible coordinates to check each pixel
for (int yVal : YArray) {
for (int xVal : XArray) {
int color = pic.getRGB(xVal, yVal); //get the color of pixel at coords (xVal, yVal)
if (color == cVal) { //if the color is equal to the one we inputted to the function
int[] cPos = {xVal, yVal}; //store the coordinates
return cPos; //return the coordinates
}
}
}
int[] returnVal = {-1,-1}; //if we didn't find it return -1, -1
return returnVal;
}
}
HiI was wondering how to flip and image horizontally, for a practce task I was given a code that reads an image, inverting it to an image indicating it's brightness from 0-5, I had to flip an image.
This is my code of my reading an image and drawing it
public int[][] readImage(String url) throws IOException
{
// fetch the image
BufferedImage img = ImageIO.read(new URL(url));
// create the array to match the dimensions of the image
int width = img.getWidth();
int height = img.getHeight();
int[][] imageArray = new int[width][height];
// convert the pixels of the image into brightness values
for (int x = 0; x < width; x++)
{
for (int y = 0; y < height; y++)
{
// get the pixel at (x,y)
int rgb = img.getRGB(x,y);
Color c = new Color(rgb);
int red = c.getRed();
int green = c.getGreen();
int blue = c.getBlue();
// convert to greyscale
float[] hsb = Color.RGBtoHSB(red, green, blue, null);
int brightness = (int)Math.round(hsb[2] * (PIXEL_CHARS.length - 1));
imageArray[x][y] = brightness;
}
}
return imageArray;
}
public void draw() throws IOException
{
int[][] array = readImage("http://sfpl.org/images/graphics/chicklets/google-small.png");
for(int i=0; i<array.length; i++)
{
for(int pic=0; pic<array[i].length; pic++)
{
if(array[pic][i] == 0)
{
System.out.print("X");
}
else if(array[pic][i] == 1)
{
System.out.print("8");
}
else if(array[pic][i] == 2)
{
System.out.print("0");
}
else if(array[pic][i] == 3)
{
System.out.print(":");
}
else if(array[pic][i] == 4)
{
System.out.print(".");
}
else if (array[pic][i] == 5)
{
System.out.print(" ");
}
else
{
System.out.print("error");
break;
}
}
System.out.println();
}
}
and this is the code I tried to create to horizontally flip it,
void mirrorUpDown()
{
int[][] array = readImage("http://sfpl.org/images/graphics/chicklets/google-small.png");
int i = 0;
for (int x = 0; x < array.length; x++)
{
for (int y = 0; y < array[i].length; y++)
{{
int temp = array[x][y];
array[x][y]= array[-x][y];
array[array[i].length-x][y]=temp;
}
}
}
}
I get an error
unreported exception java.io.IException;
must be caught or declared to be thrown
I'd actually do it by this way...
BufferedImage flip(BufferedImage sprite){
BufferedImage img = new BufferedImage(sprite.getWidth(),sprite.getHeight(),BufferedImage.TYPE_INT_ARGB);
for(int xx = sprite.getWidth()-1;xx>0;xx--){
for(int yy = 0;yy < sprite.getHeight();yy++){
img.setRGB(sprite.getWidth()-xx, yy, sprite.getRGB(xx, yy));
}
}
return img;
}
Just a loop whose x starts at the end of the first image and places its rgba value on the flipped position of the second image. Clean, easy code :)
The function mirrorUpDown() , add a throws IOException there.
Also the function from which you are calling these methods, does that handle exception, does that code enclosed in a try catch block or the function is also set to throw IOException (one of either should be there)
How is your image supposed to know it should get it's data from imageArray ?
instead, you should access the raster of your image and modify the data in it.
void flip(BufferedImage image) {
WritableRaster raster = image.getRaster();
int h = raster.getHeight();
int w = raster.getWidth();
int x0 = raster.getMinX();
int y0 = raster.getMinY();
for (int x = x0; x < x0 + w; x++){
for (int y = y0; y < y0 + h / 2; y++){
int[] pix1 = new int[3];
pix1 = raster.getPixel(x, y, pix1);
int[] pix2 = new int[3];
pix2 = raster.getPixel(x, y0 + h - 1 - (y - y0), pix2);
raster.setPixel(x, y, pix2);
raster.setPixel(x, y0 + h - 1 - (y - y0), pix1);
}
}
return;
}
Sorry about posting this here over a year later but it should aid someone at a stage
try{
java.awt.image.BufferedImage bi = javax.imageio.ImageIO.read(getClass().getResource("Your image bro.jpg")) ;
int[] h = bi.getRGB(0, 0, bi.getWidth(), bi.getHeight(), null, 0, bi.getWidth());
int [] h1 = new int[h.length];
System.out.println(""+h.length);
for(int j = 0;500>j;j++){
for(int i = 500;i>0;i--){
h1[j*500+(500-i)] = h[(j*500)+(i-1)];
}
}
bi.setRGB(0, 0, bi.getWidth(), bi.getHeight(), h1, 0, bi.getWidth());
}
catch(Exception e){e.printStackTrace();}
Lets break the code down
java.awt.image.BufferedImage bi =javax.imageio.ImageIO.read(getClass().getResource("Your image bro.jpg"));
Tries to read the image and stores the read image into the BufferedImage variable bi
int[] h = bi.getRGB(0, 0, bi.getWidth(), bi.getHeight(), null, 0, bi.getWidth());
int [] h1 = new int[h.length];
instantiate two arrays, h is the original RGB Array and h1 will be the horizontally flipped RGB array.
for(int j = 0;500>j;j++){
for(int i = 500;i>0;i--){
h1[j*500+(500-i)] = h[(j*500)+(i-1)];
}
}
Lets look at something in particular more closely
h1[j*500+(500-i)] = h[(j*500)+(i-1)];
Images are scanned from position 0;0 to x.length;y.length
but it is scanned in a coninual array. Thus we use a psuedo-array to manipulate the flipping of the image. j*500 references the Y values and (500-i) references the x values.
bi.setRGB(0, 0, bi.getWidth(), bi.getHeight(), h1, 0, bi.getWidth());
Finally, the image gets stored back into the BufferedImage variable.
Note that the 500 constant is referencing your x resolution of the image. For example, 1920 x 1080 sized image uses a max value of 1920. The logic is yours to decide.