Writing image by flipping original image horizontally - java

I wanted to flip original image horizontally and create an image in the same folder, but it does not create a new image. Thanks in advance
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
public class ImagesFlipHorizontally {
public static void main(String[] args) throws IOException {
File location1 = new File("E:\\Users/Peter/Downloads/moon1.jpg");
BufferedImage image = ImageIO.read(location1);
File location2 = new File("E:\\Users/Peter/Downloads/moon1mirror.jpg");
int width = image.getWidth();
int height = image.getHeight();
BufferedImage mirror = mirrorimage (image, width, height);
ImageIO.write(mirror, "jpg", location2);
}
private static BufferedImage mirrorimage (BufferedImage img, int w, int h) {
BufferedImage horizontallyflipped = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
for (int xx = w-1; xx > 0; xx--) {
for (int yy = 0; yy < h; yy++) {
img.setRGB(w-xx, yy, img.getRGB(xx, yy));
}
}
return horizontallyflipped;
}
}

Besides doing xx >= 0 the swapping was not done.
private static BufferedImage mirrorimage (BufferedImage img, int w, int h) {
BufferedImage horizontallyflipped = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
for (int yy = 0; yy < h; yy++) {
for (int xx = 0; xx < w/2; xx++) {
int c = img.getRGB(xx, yy);
img.setRGB(xx, yy, img.getRGB(w - 1 - xx, yy));
img.setRGB(w - 1 - xx, yy, c);
}
}
return horizontallyflipped;
}
There are faster means, like Flip Image with Graphics2D

Related

JLabel displays white image

The following code should take an image, and pixelate the areas according to the most average color, but I have to show how it works during the process not all at once, so I am trying to reattach and repaint each time but it only displays a white popup after the first image.
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.swing.JLabel;
import javax.swing.JFrame;
import javax.swing.ImageIcon;
import java.awt.Toolkit;
import java.awt.Dimension;
import javax.imageio.ImageIO;
import java.util.concurrent.TimeUnit;
class ImageUtil {
static JFrame f;
static Dimension screenSize;
static JLabel lbl;
public static BufferedImage pixelate(BufferedImage imageToPixelate, int pixelSize) {
BufferedImage pixelateImage = new BufferedImage(
imageToPixelate.getWidth(),
imageToPixelate.getHeight(),
imageToPixelate.getType());
for (int y = 0; y < imageToPixelate.getHeight(); y += pixelSize) {
for (int x = 0; x < imageToPixelate.getWidth(); x += pixelSize) {
BufferedImage croppedImage = getCroppedImage(imageToPixelate, x, y, pixelSize, pixelSize);
Color dominantColor = getDominantColor(croppedImage);
for (int yd = y; (yd < y + pixelSize) && (yd < pixelateImage.getHeight()); yd++) {
for (int xd = x; (xd < x + pixelSize) && (xd < pixelateImage.getWidth()); xd++) {
pixelateImage.setRGB(xd, yd, dominantColor.getRGB());
ImageIcon img = new ImageIcon(pixelateImage);
display(img);
}
}
}
}
return pixelateImage;
}
public static BufferedImage getCroppedImage(BufferedImage image, int startx, int starty, int width, int height) {
if (startx < 0)
startx = 0;
if (starty < 0)
starty = 0;
if (startx > image.getWidth())
startx = image.getWidth();
if (starty > image.getHeight())
starty = image.getHeight();
if (startx + width > image.getWidth())
width = image.getWidth() - startx;
if (starty + height > image.getHeight())
height = image.getHeight() - starty;
return image.getSubimage(startx, starty, width, height);
}
public static Color getDominantColor(BufferedImage image) {
int sumR = 0, sumB = 0, sumG = 0, sum2 = 0;
int color = 0;
for (int x = 0; x < image.getWidth(); x++) {
for (int y = 0; y < image.getHeight(); y++) {
color = image.getRGB(x, y);
Color c = new Color(color);
sumR += c.getRed();
sumB += c.getBlue();
sumG += c.getGreen();
sum2++;
}
}
return new Color(sumR / sum2, sumG / sum2, sumB / sum2);
}
public static void display(ImageIcon image) {
f.remove(lbl);
lbl = new JLabel(image);
f.getContentPane().add(lbl);
f.repaint();
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
String filename = args[0];
int PIX_SIZE = Integer.parseInt(args[1]);
f = new JFrame();
screenSize = Toolkit.getDefaultToolkit().getScreenSize();
f.setUndecorated(true); // removes the surrounding border
int x = (screenSize.width - f.getSize().width) / 2;
int y = (screenSize.height - f.getSize().height) / 2;
f.setLocation(x, y);
try {
BufferedImage img = ImageIO.read(new File("download.jpg"));
ImageIcon image = new ImageIcon(img);
lbl = new JLabel(image);
f.setSize(image.getIconWidth(), image.getIconHeight());
f.getContentPane().add(lbl);
f.setVisible(true);
BufferedImage imagePixelated = ImageUtil.pixelate(img, PIX_SIZE);
// ImageIO.write(imagePixelated, "jpg", new File("pixelated.jpg"));
} catch (IOException e) {
e.printStackTrace();
}
}
}
The dispay function is supposed to repaint and is called inside the pixelate function.

how to tint a black and white .png image to a certain color in Java

I have a .png image that I need to tint a custom color with the RGB values of 207, 173, 23. (https://github.com/pret/pokecrystal/blob/master/gfx/tilesets/players_room.png?raw=true)
I did some research and found the following code:
public BufferedImage getBufferedImage(String source, int redPercent, int greenPercent, int bluePercent) throws IOException{
BufferedImage img = null;
File f = null;
try{
f = new File(source);
img = ImageIO.read(f);
}catch(IOException e){
System.out.println(e);
}
int width = img.getWidth();
int height = img.getHeight();
for(int y = 0; y < height; y++){
for(int x = 0; x < width; x++){
int p = img.getRGB(x,y);
int a = (p>>24)&0xff;
int r = (p>>16)&0xff;
int g = (p>>8)&0xff;
int b = p&0xff;
p = (a<<24) | (redPercent*r/100<<16) | (greenPercent*g/100<<8) | (bluePercent*b/100);
img.setRGB(x, y, p);
}
}
return img;
}
This method is supposed to return a buffered image with the entered RGB values. However, whenever I use it, it only returns a lighter of darker version of the image with no color. I am wondering if the problem lies in the image itself, perhaps having to do with the transparency, or is the problem the code?
The problem is that the PNG image is set up to hold greyscale data only and so the BufferedImage img is also only capable of holding greyscale data. To fix this just create an output BufferedImage in RGB colour mode.
I also tidied up your exception handling.
import java.awt.image.BufferedImage;
import java.io.*;
import javax.imageio.ImageIO;
class SOQuestion {
public static BufferedImage getBufferedImage(String source,
int redPercent, int greenPercent, int bluePercent) {
BufferedImage img = null;
File f = null;
try {
f = new File(source);
img = ImageIO.read(f);
} catch (IOException e) {
System.out.println(e);
return null;
}
int width = img.getWidth();
int height = img.getHeight();
BufferedImage out = new BufferedImage(width, height,
BufferedImage.TYPE_INT_RGB);
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
int p = img.getRGB(x,y);
int a = (p>>24) & 0xff;
int r = (p>>16) & 0xff;
int g = (p>>8) & 0xff;
int b = p & 0xff;
p = (a<<24) | (redPercent*r/100<<16) |
(greenPercent*g/100<<8) | (bluePercent*b/100);
out.setRGB(x, y, p);
}
}
return out;
}
public static void main(String[] args) {
BufferedImage result = SOQuestion.getBufferedImage(args[0], 81, 68, 9);
File outputfile = new File("output.png");
try {
ImageIO.write(result, "png", outputfile);
} catch (IOException e) {
System.out.println(e);
}
}
}

Resize Buffered Image without creating new instance (java)

I was wondering if there is a way to resize a BufferedImage without creating a new instance of another image. I am wondering this because I think that it will be inefficient to create a new image each time I want to resize a BufferedImage for my application. Here is some code I've seen that explains what I don't want:
public static BufferedImage resize(BufferedImage img, int newW, int newH) {
Image tmp = img.getScaledInstance(newW, newH, Image.SCALE_SMOOTH);
BufferedImage dimg = new BufferedImage(newW, newH, BufferedImage.TYPE_INT_ARGB);
Graphics2D g2d = dimg.createGraphics();
g2d.drawImage(tmp, 0, 0, null);
g2d.dispose();
return dimg;
}
public static BufferedImage scale(BufferedImage src, int w, int h)
{
BufferedImage img =
new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
int x, y;
int ww = src.getWidth();
int hh = src.getHeight();
int[] ys = new int[h];
for (y = 0; y < h; y++)
ys[y] = y * hh / h;
for (x = 0; x < w; x++) {
int newX = x * ww / w;
for (y = 0; y < h; y++) {
int col = src.getRGB(newX, ys[y]);
img.setRGB(x, y, col);
}
}
return img;
}
private BufferedImage resize(BufferedImage src, int targetSize) {
if (targetSize <= 0) {
return src; //this can't be resized
}
int targetWidth = targetSize;
int targetHeight = targetSize;
float ratio = ((float) src.getHeight() / (float) src.getWidth());
if (ratio <= 1) { //square or landscape-oriented image
targetHeight = (int) Math.ceil((float) targetWidth * ratio);
} else { //portrait image
targetWidth = Math.round((float) targetHeight / ratio);
}
BufferedImage bi = new BufferedImage(targetWidth, targetHeight, src.getTransparency() == Transparency.OPAQUE ? BufferedImage.TYPE_INT_RGB : BufferedImage.TYPE_INT_ARGB);
Graphics2D g2d = bi.createGraphics();
g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR); //produces a balanced resizing (fast and decent quality)
g2d.drawImage(src, 0, 0, targetWidth, targetHeight, null);
g2d.dispose();
return bi;
}
Thank you for any responses!

Converting subimage to RGB-A

I am working on a 2D platform game and I have a sprite sheet which includes the sprites of tiles and blocks.
I noticed that there was a pink-ish background behind the transparent sprites so I thought that Java wasn't loading the sprites as PNG and I tried to re-draw the sprite on a new bufferedImage, pixel by pixel checking if the pixel was R=255, G=63, B=52 but unfortunately, the code wasn't able to detect that either and at this point I have no more options left to try.
I made sure that the "pink" color values are correct by using a color picker.
original spritesheet (transparent):
The class that loads the sprite(s) is:
public class SpriteSheet {
private BufferedImage image;
public SpriteSheet(BufferedImage image) {
this.image = image;
}
public BufferedImage grabImage(int col, int row, int width, int height) {
BufferedImage alpha = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
BufferedImage img = image.getSubimage(
(col * width) - width,
(row * height) - height,
width,
height);
int w = img.getWidth();
int h = img.getHeight();
for(int y = 0; y < h; y++) {
for(int x = 0; x < w; x++) {
int pixel = img.getRGB(x, y);
int red, green, blue;
red = (pixel >> 16) & 0xff;
green = (pixel >> 8) & 0xff;
blue = (pixel) & 0xff;
if(red == 255 && green == 63 && blue == 52)
alpha.setRGB(x, y, new Color(0, 0, 0, 0).getRGB());
else
alpha.setRGB(x, y, pixel);
}
}
return alpha;
}
}
the class that loads the sprite sheet is:
public class Texture {
SpriteSheet bs, ss;
private BufferedImage block_sheet = null;
public BufferedImage[] block = new BufferedImage[3];
public Texture() {
BufferedImageLoader loader = new BufferedImageLoader();
try {
block_sheet = loader.loadImage("/tiles.png");
} catch(Exception e) {
e.printStackTrace();
}
bs = new SpriteSheet(block_sheet);
getTextures();
}
private void getTextures() {
block[0] = bs.grabImage(1, 1, 32, 32);
block[1] = bs.grabImage(2, 1, 32, 32);
block[2] = bs.grabImage(4, 1, 32, 32);
}
}
How do I get rid of the pink-ish background and keep transparency?
I dont understand why you're using subImage.
try {
BufferedImage img = ImageIO.read(new File("D:/image.png"));
for (int i = 0; i < img.getWidth(); i++) {
for (int j = 0; j < img.getHeight(); j++) {
Color pixelcolor = new Color(img.getRGB(i, j));
int r = pixelcolor.getRed();
int g = pixelcolor.getGreen();
int b = pixelcolor.getBlue();
if (r == 255 && g == 63 && b == 52) {
int rgb = new Color(255, 255, 255).getRGB();
img.setRGB(i, j, rgb);
}
}
}
ImageIO.write(img, "png", new File("D:/transparent.png"));
} catch (Exception e) {
System.err.println(e.getMessage());
}
cough, It worked all along, I had forgotten to disable the test blocks which was representing the blocks. Realized this after some time.
So the transparency was working fine. I just saw the rectangle i was drawing behind it.

Sobel edge detection creates noise

I tried to implement the Sobel edge detection in java.
It kind of works but I get a lot of seemingly random noise...
I loaded the image as BufferedImages and converted those to greyscaleimages first (via an algorithm i found online). After that I calculate the edges in x and y direction.
This is my code:
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
public class Sobel {
static int [] sobel_x = {1, 0, -1,
2, 0, -2,
1, 0, -1};
static int [] sobel_y = {1, 2, 1,
0, 0, 0,
-1, -2, -1};
public static void main(String argc[]) throws IOException {
BufferedImage imgIn = ImageIO.read(new File("test.jpeg"));
BufferedImage imgGrey = greyscale(imgIn);
ImageIO.write(imgGrey, "PNG", new File("greyscale.jpg"));
BufferedImage edgesX = edgeDetection(imgGrey, sobel_x);
ImageIO.write(edgesX, "PNG", new File("edgesX.jpg"));
BufferedImage edgesY = edgeDetection(imgGrey, sobel_y);
ImageIO.write(edgesY, "PNG", new File("edgesY.jpg"));
BufferedImage sobel = sobel(edgesX,edgesY);
ImageIO.write(sobel, "PNG", new File("sobel.jpg"));
}
private static BufferedImage sobel (BufferedImage edgesX, BufferedImage edgesY){
BufferedImage result = new BufferedImage(edgesX.getWidth(), edgesX.getHeight(), BufferedImage.TYPE_BYTE_GRAY);
int height = result.getHeight();
int width = result.getWidth();
for(int x = 0; x < width ; x++){
for(int y = 0; y < height; y++){
int tmp = Math.abs(edgesX.getRGB(x, y) + Math.abs(edgesY.getRGB(x, y)));
result.setRGB(x, y, tmp);
}
}
return result;
}
private static BufferedImage edgeDetection(BufferedImage img, int[] kernel){
int height = img.getHeight();
int width = img.getWidth();
BufferedImage result = new BufferedImage(width -1, height -1, BufferedImage.TYPE_BYTE_GRAY);
for(int x = 1; x < width -1 ; x++){
for(int y = 1; y < height - 1; y++){
int [] tmp = {img.getRGB(x-1, y-1),img.getRGB(x, y-1),img.getRGB(x+1, y-1),img.getRGB(x-1, y),img.getRGB(x, y),img.getRGB(x+1, y),img.getRGB(x-1, y+1),img.getRGB(x, y+1),img.getRGB(x+1, y+1)};
int value = convolution (kernel, tmp);
result.setRGB(x,y, value);
}
}
return result;
}
private static int convolution (int [] kernel, int [] pixel){
int result = 0;
for (int i = 0; i < pixel.length; i++){
result += kernel[i] * pixel[i];
}
return result / 9;
}
private static BufferedImage greyscale(BufferedImage img){
//get image width and height
int width = img.getWidth();
int height = img.getHeight();
//convert to grayscale
for(int y = 0; y < height; y++){
for(int x = 0; x < width; x++){
int p = img.getRGB(x,y);
int a = (p>>24)&0xff;
int r = (p>>16)&0xff;
int g = (p>>8)&0xff;
int b = p&0xff;
//calculate average
int avg = (r+g+b)/3;
//replace RGB value with avg
p = (a<<24) | (avg<<16) | (avg<<8) | avg;
img.setRGB(x, y, p);
}
}
return img;
}
}
And this is an example of the noise I'm talking about:
An image of Lena :
I don't know why I get all this noise.
Any advice is appreciated.
You have to make the following changes:
in convolution take the absolute value
private static int convolution (int [] kernel, int [] pixel){
int result = 0;
for (int i = 0; i < pixel.length; i++){
result += kernel[i] * pixel[i];
}
return (int)(Math.abs(result) / 9);
}
in edgeDetection apply the value to all three channels
private static BufferedImage edgeDetection(BufferedImage img, int[] kernel){
int height = img.getHeight();
int width = img.getWidth();
BufferedImage result = new BufferedImage(width -1, height -1, BufferedImage.TYPE_INT_RGB);
for(int x = 1; x < width -1 ; x++){
for(int y = 1; y < height - 1; y++){
int [] tmp = {img.getRGB(x-1, y-1)&0xff,img.getRGB(x, y-1)&0xff,img.getRGB(x+1, y-1)&0xff,
img.getRGB(x-1, y)&0xff,img.getRGB(x, y)&0xff,img.getRGB(x+1, y)&0xff,img.getRGB(x-1, y+1)&0xff,
img.getRGB(x, y+1)&0xff,img.getRGB(x+1, y+1)&0xff};
int value = convolution (kernel, tmp);
result.setRGB(x,y, 0xff000000|(value<<16)|(value<<8)|value);
}
}
return result;
}
And finally declare the images as INT_RGB type
BufferedImage result = new BufferedImage(edgesX.getWidth(), edgesX.getHeight(), BufferedImage.TYPE_INT_RGB);
BufferedImage result = new BufferedImage(width -1, height -1, BufferedImage.TYPE_INT_RGB);

Categories