ImageIO.write not writing image into folder - java

I am working on a project in which I am trying to store all the pixels of a jpg image in an array, and then using that array to write a copy of the original image in a different folder. However, I do not seem to be able to write the copy into the folder. I know that the issue has something to do with the copy of the image I created, since the writing works perfectly if I use the original image as the parameter in ImageIO.write, but i'm still not entirely sure what the issue is. Does anyone know what sort of error I may be encountering, and what I could do to fix it? (For additional context, I know that reading/writing can be implemented without using arrays, but I want to use arrays to implement this)
Code for reference:
package com.company;
import java.io.File;
import java.util.Scanner;
import java.util.concurrent.*;
import java.io.IOException;
import java.awt.image.BufferedImage;
import javax.imageio.ImageIO;
public class filereader {
public static void main(String[] args) throws IOException {
int width = 1536;
int height = 2048;
BufferedImage image = null;
BufferedImage newimage = null;
int[][] newarray = new int[height][width];
File f = null;
File g = null;
try {
System.out.println("Insert your file");
Scanner scanney = new Scanner(System.in);
String arg1 = scanney.next();
f = new File(arg1);
image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
image = ImageIO.read(f);
for (int i = 0; i < height; i++) {
for (int j = 0; j < width; j++) {
newarray[i][j] = image.getRGB(j, i);
}
}
} catch (IOException e) {
System.out.println("Error:" + e);
}
try {
newimage = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
System.out.println(newimage.getType());
for (int i = 0; i < height; i++) {
for (int j = 0; j < width; j++) {
int newimagestuff = newarray[i][j];
newimage.setRGB(j, i, newimagestuff);
}
}
int i = 0;
g = new File("C:\\Users\\user1\\Documents\\File Reading\\Outputest.jpg");
ImageIO.write(newimage,"jpg", g);
System.out.println(newimage);
System.out.println(image);
} catch (IOException e) {
System.out.println("Error:" + e);
}
}
}

There are several issues with your code:
You create two new BufferedImages - the first one is completely useless as you are overwriting it in the next line with the result of ImageIO.read().
The second BufferedImage you create has the type BufferedImage.TYPE_INT_ARGB which is probably wrong as JPG images don't have an alpha channel (thats the "A" in the type). You rather should use the type of the image read in with ImageIO.
Also why do you copy pixel by pixel when you could read always a complete row - if it has to be a two-dimensional array for intermediate storage - or even the complete image at once - if a single-dimensional image would suffice. You can use public int[] getRGB​(int startX, int startY, int w, int h, int[] rgbArray, int offset, int scansize) and the matching setRGB method for this.

I think escaping the space in your file path might help. Like that:
g = new File("C:\\Users\\user1\\Documents\\File\ Reading\\Outputest.jpg");

Related

Java - Random Image maker / embed printer

So I have an EmbedBuilder (part of discord api / library for java) and I'm trying to create an image that would contain 8 smaller random images
these images would randomly selected from a file within the project. say resourced/images/.
I just don't know what function would allow me to take those images and combine them / resize them in anyway that I need.
Example:
Here is a snippet that copies one image into another by going one coordinate at a time and copying RGB over to a new file. It shouldn't be any problem for you to adjust the code to copy several images into one bigger image by adjusting coordinates
public static void copyImage(int height, int width) throws IOException {
BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
BufferedImage imageToCopy = ImageIO.read(new File("imageToCopy.png"));
for (int i = 0; i < imageToCopy.getWidth(); i++) {
for (int j = 0; j < imageToCopy.getHeight(); j++) {
int rgb = imageToCopy.getRGB(i, j);
bufferedImage.setRGB(i, j, rgb);
}
}
File resultFile = new File("resultImage.png");
ImageIO.write(bufferedImage, "png", resultFile);
}

Creating a Image from javafx2 2d Color list using bufferImage

I am trying to convert my 2d list of Colors to an actual image and then export it, however, when I try to use it, it distorts the colors (shows the wrong ones)
import javafx.scene.paint.Color;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.List;
import javax.imageio.ImageIO;
public class ImageAction {
public static void fromColorGrid(List<List<Color>> colorGrid) {
int width = colorGrid.size();
int height = colorGrid.get(0).size();
BufferedImage buffImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
// Set each pixel of the BufferedImage to the color from the Color[][].
for (int x = 0; x < width; x++) {
for (int y = 0; y < height; y++) {
String colorStr = colorGrid.get(x).get(y).toString().replace("0x", "");
int rgb = Integer.parseInt(colorStr, 16);
System.out.println(colorStr + " " + rgb);
buffImage.setRGB(x, y, rgb);
}
}
try {
File outputfile = new File("saved.png");
ImageIO.write(buffImage, "png", outputfile);
} catch (IOException e) {
System.out.println("Ups");
}
}
}
Where am I going wrong?
This bit seems odd to me:
String colorStr = colorGrid.get(x).get(y).toString().replace("0x", "");
int rgb = Integer.parseInt(colorStr, 16);
System.out.println(colorStr + " " + rgb);
buffImage.setRGB(x, y, rgb);
That code relies on toString() method of JavaFX's color class, which explicitly states:
This method is intended to be used only for informational purposes. The content and format of the returned string might vary between implementations.
Instead, just convert directly to an AWT color using the RGB values:
Color fxColor = colorGrid.get(x).get(y);
java.awt.Color awtColor = new java.awt.Color((float) fxColor.getRed(),
(float) fxColor.getGreen(),
(float) fxColor.getBlue(),
(float) fxColor.getOpacity());
buffImage.setRGB(x, y, awtColor.getRGB());
The above doesn't rely on any particular toString() implementation, and in my quick tests the code seems to work fine with it in place.

Can somebody explain why this code does not color every other pixel column in the image red?

This code is a test for a larger program I'm building. It is supposed to color every other pixel row in the image red, but the result is the image added below. Can somebody explain why the red isn't showing?
package code;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;
import javax.imageio.ImageIO;
public class Pixel {
BufferedImage image;
int width;
int height;
public Pixel() throws IOException {
File input = new File("/Users/SanchitBatra/Desktop/Depixelator.jpg");
image = ImageIO.read(input);
width = image.getWidth();
height = image.getHeight();
}
public void changePixels() throws IOException{
for(int i=0; i<height; i++){
for(int j=0; j<width; j++){
int red;
// Color c = new Color(image.getRGB(j, i));
if(i%2==0){
red = 255;
}
else{
red=0;
}
int green = 0;
int blue = 0;
Color newColor = new Color(red, green, blue);
image.setRGB(j,i,newColor.getRGB());
}
}
File output = new File("/Users/SanchitBatra/Desktop/grayscale.jpg");
ImageIO.write(image, "jpg", output);
}
static public void main(String args[]) throws Exception {
Pixel obj = new Pixel();
obj.changePixels();
}
}
This is the resulting image:
Edit: The program is doing exactly what it should using a coloured image as a source. Thanks to all contributions! I learnt a lot today :)
Try this:
public void changePixels() throws IOException{
BufferedImage bi = new BufferedImage(side,side,BufferedImage.TYPE_INT_ARGB);
int[] pixels = new int[width*height];
for(int i=0; i<height; i++){
for(int j=0; j<width; j++){
int colorIn = image.getRGB(j,i);
int redIn = 255&(colorIn<<16);
int greenIn = 255&(colorIn<<8);
int blueIn = 255&(colorIn);
if(i%2==0){
redIn = 255;
}
pixels[i+j*width] = (255<<24)|(redIn<<16)|(greenIn<<8)|blueIn;
}
}
bi.setRGB(0, 0, width, height, pixels, 0, width);
File output = new File("/Users/SanchitBatra/Desktop/grayscale.jpg");
ImageIO.write(bi, "jpg", output);
}
I showed you how to pull the color values out using bit shifting here to show you how to have a little bit more control over your process. This also retains the original pixel values and just overwrites the red value if it is an even column.
If you want to make columns red, you should make them red along the width instead of the height. The current code will make alternate rows red.
I think your code is OK, try to zoom in/out in your image to see if you are getting the desired effects.
Thanks,
Hassaan

generating design with java

i am trying to generate following given sateen design with help of my java code but this code is not creating png file named sateen
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
public class Sateen {
BufferedImage image;
int width;
int height;
int red,green,blue;
public Sateen() {
try {
File input = new File("n.png");
image = ImageIO.read(input);
width = image.getWidth();
height = image.getHeight();
//n is png file with only white pixels
for(int i=0; i<height; i++){
for(int j=0; j<width; j++){
Color p = new Color(image.getRGB(j, i));
Color g = new Color(image.getRGB(j+5, i));
//getting (j,i) coordinate pixel value and then comparing it to next 5th pixel
if(p.getRed()==255&&p.getBlue()==255&&p.getGreen()==255&&g.getRed()==255&&
g.getBlue()==255&&g.getGreen()==255)
{ red=0;
blue=0;
green=0; }
//if both pixel value is white then setting 5th pixel value to black
Color newColor = new Color(red,green,blue);
image.setRGB(j+5,i,newColor.getRGB());
j=j+5;
}
}
File ouptut = new File("Sateen.png");
ImageIO.write(image, "png", ouptut);
//creating sateen png file
} catch (Exception e) {}
}
static public void main(String args[]) throws Exception
{
Sateen obj = new Sateen();
}
}
Seems to actually create a .png file (make sure the filepath is correct?). However this code will not generate a sateen pattern, rather draws black pixels at column 6, 12, 18 etc.
The following code fixes some issues in your code. Although it produces an output file but the output file does not look like what you are trying to produce. Perhaps you need to tweak your algorithm?
Anyway the main thing to learn here is that if you are looping over arrays and incrementing the index within the loop then you need to take care of the situation where your index might go out of bounds of the array i.e. your j+5 can be anything outside the image.
Also, make sure that your input file is in the correct location which will depend on where you run the program from. If you run it from the debugger/IDE then it should be inside the project folder next to the src folder. It would be better if you specify full path to your file i.e. C:\SomeFolder\n.png to avoid input file missing error.
Finally, use something like e.printStackTrace(); in your catch block to find out where and why your code is failing.
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
public class Sateen {
BufferedImage image;
int width;
int height;
int red, green, blue;
public Sateen() {
try {
File input = new File("n.png");
image = ImageIO.read(input);
width = image.getWidth();
height = image.getHeight();
// n is png file with only white pixels
for (int i = 0; i < height; i++) {
for (int j = 0; j < width; j++) { // may not need j++ as you are doing j+5?
Color p = new Color(image.getRGB(j, i));
int jPlus5 = j + 5;
if (jPlus5 < width) {
Color g = new Color(image.getRGB(jPlus5, i));
// getting (j,i) coordinate pixel value and then
// comparing
// it to next 5th pixel
if (p.getRed() == 255 && p.getBlue() == 255 && p.getGreen() == 255 && g.getRed() == 255 &&
g.getBlue() == 255 && g.getGreen() == 255)
{
red = 0;
blue = 0;
green = 0;
}
// if both pixel value is white then setting 5th pixel
// value
// to black
Color newColor = new Color(red, green, blue);
image.setRGB(jPlus5, i, newColor.getRGB());
}
j = jPlus5;
}
}
File ouptut = new File("Sateen.png");
ImageIO.write(image, "png", ouptut);
// creating sateen png file
} catch (Exception e) {
e.printStackTrace();
}
}
static public void main(String args[]) throws Exception
{
Sateen obj = new Sateen();
}
}

How to flip and save Image

My Image declaration:
ImageIcon imageIcon1 = new ImageIcon(main.class.getResource("image1.png"));
Image image1 = imageIcon1.getImage();
How do I take image1, flip it along it's vertical axis and save it as another image?
I have googled and every solution I have found has come with some type of casting error.
Also, if there is a more efficient way to declare my image please let me know.
You state:
I have googled and every solution I have found has come with some type of casting error.
Which only tells us that you're doing something wrong but doesn't tell us what, limiting how we can help you. I can only tell you some steps that have worked for me:
Create another BufferedImage the same size as the first,
get its Graphics2D context via createGraphics(),
flip the graphics via an AffineTransform.getScaleInstance(-1, 1) for a horizontal flip
Don't forget to then translate the transform to bring the flipped image to where you want it.
draw the old image into the new image,
dispose the Graphics2D object.
If you need more help, then please show us what you've tried and include any and all error messages.
For instance, I played with this when playing with mirror sprite images a while back. Compile and run this to see what I mean:
import java.awt.Graphics2D;
import java.awt.GridLayout;
import java.awt.event.*;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import javax.imageio.ImageIO;
import javax.swing.*;
public class FlipViaTransform {
private static final String SPRITE_SHEET_SPEC = "http://www.funorb.com/img/images/game/"
+ "central/dev_diary/sprite_sheet_full.gif";
private static final int TIMER_DELAY = 200;
private static final int SPRITE_ROWS = 8; // an 8 x 8 sprite sheet
public static void main(String[] args) {
try {
URL spriteSheetUrl = new URL(SPRITE_SHEET_SPEC);
BufferedImage spriteSheet = ImageIO.read(spriteSheetUrl);
final ImageIcon[] iconsA = new ImageIcon[64];
final ImageIcon[] iconsB = new ImageIcon[64];
double wD = (double) spriteSheet.getWidth() / SPRITE_ROWS;
double hD = (double) spriteSheet.getHeight() / SPRITE_ROWS;
int w = (int) wD;
int h = (int) hD;
// *** here's what I used to flip
AffineTransform at = AffineTransform.getScaleInstance(-1, 1); // *** flip
at.translate(-wD, 0); // *** translate so that flipped image is visible
for (int i = 0; i < SPRITE_ROWS; i++) {
for (int j = 0; j < SPRITE_ROWS; j++) {
int x = (int) (i * wD);
int y = (int) (j * hD);
BufferedImage imgA = spriteSheet.getSubimage(x, y, w, h);
BufferedImage imgB = new BufferedImage(imgA.getWidth(),
imgA.getHeight(), BufferedImage.TYPE_INT_ARGB);
Graphics2D g2 = imgB.createGraphics();
g2.setTransform(at); // *** transform
g2.drawImage(imgA, 0, 0, null); // *** draw old image into new
g2.dispose(); // *** get rid of graphics2d object
iconsA[j * SPRITE_ROWS + i] = new ImageIcon(imgA);
iconsB[j * SPRITE_ROWS + i] = new ImageIcon(imgB);
}
}
final JLabel labelA = new JLabel("Image");
final JLabel labelB = new JLabel("Mirror Image");
labelA.setVerticalTextPosition(JLabel.BOTTOM);
labelB.setVerticalTextPosition(JLabel.BOTTOM);
labelA.setHorizontalTextPosition(JLabel.CENTER);
labelB.setHorizontalTextPosition(JLabel.CENTER);
labelA.setIcon(iconsA[0]);
labelB.setIcon(iconsB[0]);
final JPanel panel = new JPanel(new GridLayout(1, 0));
panel.add(labelA);
panel.add(labelB);
Timer spriteTimer = new Timer(TIMER_DELAY, new ActionListener() {
int spriteIndex = 0;
#Override
public void actionPerformed(ActionEvent arg0) {
labelA.setIcon(iconsA[spriteIndex]);
labelB.setIcon(iconsB[spriteIndex]);
spriteIndex++;
spriteIndex %= iconsA.length;
}
});
spriteTimer.start();
JOptionPane.showMessageDialog(null, panel, "AffineTransform Example", JOptionPane.PLAIN_MESSAGE);
spriteTimer.stop();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
which displays as:
I have never done this, but you can try to research if you can use a 3d party library such as ImageMagick or GraphicsMagic with Java. Those libraries can read PNG images and perform graphics operation on them.

Categories