generating design with java - 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();
}
}

Related

ImageIO.write not writing image into folder

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");

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

Color converting in java

I am wanting to get rgb value of each pixel in an image. For this I used getRGB() which returns an integer that I converted with Color(arg,true). If I print out the getRGB() results and paste one of the numbers into the Color class it works. But if make an integer as shown equal rgb and put it in Color so I can cycle through each pixel it returns 255 for all values.
import java.awt.Color;
import java.awt.image.BufferedImage;
import java.awt.image.DataBufferInt;
import java.io.File;
import java.io.IOException;
import javax.imageio.*;
public class kmeans {
public static void main(String[] args) throws IOException {
File file = new File("andy.jpg");
BufferedImage image = ImageIO.read(file);
int width = image.getWidth();
int height = image.getHeight();
for (int i = 0; i < width; i++) {
for (int j = 0; j < height; j++) {
int rgb = image.getRGB(i, j);
// System.out.println(rgb);
Color c = new Color(rgb, true);
// System.out.println(c.getRed()+" "+c.getGreen()+" "+c.getBlue()+" ");
System.out.println(c);
}
}
}
}
Have you tried setting new Color(rgb, true) to new Color(rgb, false)? When you get the int value for rgb, you don't get the alpha value (aka the transparency of the current pixel). When using that value in the constructor, without having an alpha value, it could mess with the results.
I think your code is fine and the problem, assuming there is one, is elsewhere. Here is a sample of the output your code produced for some random JPEG:
java.awt.Color[r=126,g=116,b=104]
java.awt.Color[r=122,g=112,b=100]
java.awt.Color[r=116,g=106,b=94]
java.awt.Color[r=117,g=107,b=95]
java.awt.Color[r=123,g=113,b=101]
java.awt.Color[r=122,g=112,b=100]

Replace all occurrences of one image inside another image

In Java, I'm trying to replace one BufferedImage inside another BufferedImage.
For example, could be replaced with inside , so that is produced as a result.
Would it be possible to write a function that would replace one BufferedImage inside another BufferedImage, and return the resulting BufferedImage?
public static BufferedImage replaceInsideBufferedImage(BufferedImage containingImage, BufferedImage toBeReplaced, BufferedImage replaceWithThis){
//In containingImage, replace all occurrences of toBeReplaced with replaceWithThis
}
The method below does the trick. Pseudo-code:
(1) For every pixel of containingImage :
Begin matching the toBeReplaced (pixel by pixel)
If it finds it (all pixels matched), it goes and replaces all of them with replaceWithThis
If not, goes back to (1)
As all patterns will be found, finally, it will return returnImage .
replaceInsideBufferedImage() code:
public static BufferedImage replaceInsideBufferedImage(BufferedImage containingImage, BufferedImage toBeReplaced, BufferedImage replaceWithThis) {
BufferedImage returnImage = deepCopyImage(containingImage);
for (int x = 0; x+toBeReplaced.getWidth() < containingImage.getWidth(); x++) {
for (int y = 0; y+toBeReplaced.getHeight() < containingImage.getHeight(); y++) {
BufferedImage subImg = containingImage.getSubimage(x, y, toBeReplaced.getWidth(), toBeReplaced.getHeight());
if (imageEquals(subImg,toBeReplaced)) {
for (int sx = 0; sx < replaceWithThis.getWidth(); sx++) {
for (int sy = 0; sy < replaceWithThis.getHeight(); sy++) {
returnImage.setRGB(x+sx, y+sy, replaceWithThis.getRGB(sx, sy));
}
}
}
}
}
return returnImage;
}
Full working code:
import java.awt.image.BufferedImage;
import java.awt.image.ColorModel;
import java.awt.image.WritableRaster;
import java.io.File;
import javax.imageio.ImageIO;
public class ReplacePattern {
public static void main(String[] args) throws Exception {
BufferedImage containingImage = ImageIO.read(new File("fourWhites.png"));
BufferedImage toBeReplaced = ImageIO.read(new File("oneWhite.png"));
BufferedImage replaceWithThis = ImageIO.read(new File("oneRed.png"));
BufferedImage replaced = replaceInsideBufferedImage(containingImage, toBeReplaced, replaceWithThis);
ImageIO.write(replaced, "png", new File("fourReds.png"));
}
public static BufferedImage replaceInsideBufferedImage(BufferedImage containingImage, BufferedImage toBeReplaced, BufferedImage replaceWithThis) {
BufferedImage returnImage = deepCopyImage(containingImage);
for (int x = 0; x+toBeReplaced.getWidth() < containingImage.getWidth(); x++) {
for (int y = 0; y+toBeReplaced.getHeight() < containingImage.getHeight(); y++) {
BufferedImage subImg = containingImage.getSubimage(x, y, toBeReplaced.getWidth(), toBeReplaced.getHeight());
if (imageEquals(subImg,toBeReplaced)) {
for (int sx = 0; sx < replaceWithThis.getWidth(); sx++) {
for (int sy = 0; sy < replaceWithThis.getHeight(); sy++) {
returnImage.setRGB(x+sx, y+sy, replaceWithThis.getRGB(sx, sy));
}
}
}
}
}
return returnImage;
}
// http://stackoverflow.com/a/3514297/1850609
public static BufferedImage deepCopyImage(BufferedImage bi) {
ColorModel cm = bi.getColorModel();
boolean isAlphaPremultiplied = cm.isAlphaPremultiplied();
WritableRaster raster = bi.copyData(null);
return new BufferedImage(cm, raster, isAlphaPremultiplied, null);
}
// http://stackoverflow.com/a/11006474/1850609
private static boolean imageEquals(BufferedImage image1, BufferedImage image2) {
int width;
int height;
boolean imagesEqual = true;
if( image1.getWidth() == ( width = image2.getWidth() ) &&
image1.getHeight() == ( height = image2.getHeight() ) ){
for(int x = 0;imagesEqual == true && x < width; x++){
for(int y = 0;imagesEqual == true && y < height; y++){
if( image1.getRGB(x, y) != image2.getRGB(x, y) ){
imagesEqual = false;
}
}
}
}else{
imagesEqual = false;
}
return imagesEqual;
}
}
It would be possible, however I would not suggest doing that.
Detecting whether an image is present within another image will be very slow.
Moreover, due to possible encoding artifacts, it is possible that an image will never be detected in another image. In such case you would have to implement a more flexible detection function, which will take even longer and may lead to false positives.
Most likely, you have the data to rebuild the image from scratch. Instead of operating on images simply get the data used to generate the initial image and create a new one based on it.
But if you really need to do it, you will have to loop over both images and compare pixels. Use getRGB() function and compare the images pixel by pixel.

Making a Certain Color on a BufferedImage Become Transparent

A very similar question that has been answered: How to make a color transparent in a BufferedImage and save as PNG
Unfortunately I couldn't formulate an answer for myself out of that source.
Q: I draw a BufferedImage to my Canvas and would simply like to create a method that turns every pixel with the a certain color (in this case: [214, 127, 255] / 0xD67FFF) into a transparent one. The BufferedImage is of type ARGB.
I do not want to save the BufferedImage as a file, simply display it on my canvas.
Thanks in advance.
Iterate over all the pixels and perform the check and make transparent.
for (int y = 0; y < image.getHeight(); ++y) {
for (int x = 0; x < image.getWidth(); ++x) {
int argb = image.getRGB(x, y);
if ((argb & 0x00FFFFFF) == 0x00D67FFF)
{
image.setRGB(x, y, 0);
}
}
}
Make sure the BufferedImage uses an alpha channel, otherwise it will become black.
Note that this will affect your original image.
Edit: Note that I changed the check. Therefor it wouldn't have worked because of I assume your pixels were solid (alpha = 255).
(0xFFD67FFF & 0x00FFFFFF) will result in 0x00D67FFF
And, (0x00D67FFF == 0x00D67FFF)
For a complete solution, like loading, processing and writing, you can use this code:
import java.awt.Color;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
public class TransparentConverter {
private static final Color backColor = Color.GREEN;
private static final int THRESHOLD = 70;
private static final int TRANSPARENT = 0; // 0x00000000;
static File base = new File("C:\\images");
static File base2 = new File("C:\\images2");
public static void main(String[] args) throws IOException {
System.out.println("TransparentConverter.main()");
for (File file : base.listFiles()) {
System.out.println(file);
BufferedImage initImage = ImageIO.read(file);
int width = initImage.getWidth(null),
height = initImage.getHeight(null);
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
Graphics g = image.getGraphics();
g.drawImage(initImage, 0, 0, null);
//System.out.println("before: " + image.getRGB(0, 0));
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
int pixel = image.getRGB(x, y);
Color color = new Color(pixel);
int dr = Math.abs(color.getRed() - backColor.getRed()),
dg = Math.abs(color.getGreen() - backColor.getGreen()),
db = Math.abs(color.getBlue() - backColor.getBlue());
if (dr < THRESHOLD && dg < THRESHOLD && db < THRESHOLD) {
image.setRGB(x, y, TRANSPARENT);
}
}
}
//System.out.println(" after: " + image.getRGB(0, 0));
file = new File(base2, file.getName());
//System.out.println(" " + file);
ImageIO.write(image, "png", file);
}
}
}

Categories