Let's say I have an image called testimage.jpg, and want to cross-stitch it with a DMC 208 floss (RGB value: 148,91,128)
I got these hints:
Read each pixel's RGB value
Compare it with the floss
Use bilinear interpolation for image scaling
Use Euclidean distance to get the closest color
I think I already figured out how to do step 1. Now I'm wondering how to do step 2, and 4.
BufferedImage img = ImageIO.read(new File("testimage.jpg"));
int imgWidth = img.getWidth();
int imgHeight = img.getHeight();
Color dmc208 = new Color(148,91,128);
Color currentPixel = null;
for (int x = 0; x < imgWidth; x++){
for (int y = 0; y < imgHeight; y++){
currentPixel = new Color(img.getRGB(x, y));
}
}
I know how to calculate the Eulicdean distance, but how to get the"closest" color at that distance?
Related
I have a squared PGraphics where I want to read the color of each pixel. I do this with the following lines:
size(1080,1080, P2D);
pg = createGraphics(width, height, P2D);
…then in draw:
pg.loadPixels();
for (int y = 0; y < pixel; y++) {
for (int x = 0; x < pixel; x++) {
int ix = int(size*x);
int iy = int(size*y);
color c = pg.pixels[iy * width + ix];
However, if I now change the size so that the PGrpahics or my sketch window is no longer squared I get an ArrayIndexOutOfBoundsException error message. I know that you can also read the pixels from rectangular sketches, for example with:
pixels[x+y*width] = …etc
Works fine – but what is it that I am missing above if I change the size to lets say size(1920,1080, P2D);?
For an automation tool I'm working on I need to compare 2 images.
My code works perfectly when I have "normal" images, but it fails when one of the images has a transparent area.
I'm reducing the color between the images for each pixel and creating a negative image that shows the difference. For images with transparent area the negative image is whole white, I can't see any shape or other info.
How to ignore the transparent area (shown in the images as gray color)?
My code:
private static BufferedImage createDiffImage(BufferedImage img1, BufferedImage img2) {
BufferedImage result = new BufferedImage(img1.getWidth(), img1.getHeight(), img1.getType());
int color;
for(int x = 0; x < img1.getWidth(); x++)
for(int y = 0; y < img1.getHeight(); y++) {
color = Math.abs(img2.getRGB(x, y) - img1.getRGB(x, y));
result.setRGB(x, y, color);
}
return result;
}
I found the solution:
private static BufferedImage createDiffImage(BufferedImage img1, BufferedImage img2) {
BufferedImage result = new BufferedImage(img1.getWidth(), img1.getHeight(), img1.getType());
for(int x = 0; x < img1.getWidth(); x++)
for(int y = 0; y < img1.getHeight(); y++) {
Color c1 = new Color(img1.getRGB(x,y));
Color c2 = new Color(img2.getRGB(x,y));
int alpha = 255;
int red = Math.abs(c1.getRed() - c2.getRed());
int green = Math.abs(c1.getGreen() - c2.getGreen());
int blue = Math.abs(c1.getBlue() - c2.getBlue());
Color negativeColor = new Color(red,green,blue, alpha);
result.setRGB(x, y, negativeColor.getRGB());
}
return result;
}
So this method I wrote gets the mean and standard deviation of an image. I am trying to modify this to get the mean and standard deviation of the red, green and blue values of an image. But I am stumped on how to do to so. I tried to use a colorModel but I was getting nowhere. Could anyone give me some advice on how to modify this code to get the mean and standard deviation of the red, green and blue values?
public static double redValues(BufferedImage image){
Raster raster = image.getRaster();
double mean = meanValue(image);
double sumOfDiff = 0.0;
Color c = new Color(image.getRGB(0, 0));
int red = c.getRed();
for (int y = 0; y < image.getHeight(); ++y){
for (int x = 0; x < image.getWidth(); ++x){
double r = raster.getSample(x, y, red) - mean;
sumOfDiff += Math.pow(r, 2);
}
}
return sumOfDiff / ((image.getWidth() * image.getHeight()) - 1);
}
But this still returns a mean brightness value. When I want to get the red value.
I'm looking to use a very crude heightmap I've created in Photoshop to define a tiled isometric grid for me:
Map:
http://i.imgur.com/jKM7AgI.png
I'm aiming to loop through every pixel in the image and convert the colour of that pixel to a scale of my choosing, for example 0-100.
At the moment I'm using the following code:
try
{
final File file = new File("D:\\clouds.png");
final BufferedImage image = ImageIO.read(file);
for (int x = 0; x < image.getWidth(); x++)
{
for (int y = 0; y < image.getHeight(); y++)
{
int clr = image.getRGB(x, y) / 99999;
if (clr <= 0)
clr = -clr;
System.out.println(clr);
}
}
}
catch (IOException ex)
{
// Deal with exception
}
This works to an extent; the black pixel at position 0 is 167 and the white pixel at position 999 is 0. However when I insert certain pixels into the image I get slightly odd results, for example a gray pixel that's very close to white returns over 100 when I would expect it to be in single digits.
Is there an alternate solution I could use that would yield more reliable results?
Many thanks.
Since it's a grayscale map, the RGB parts will all be the same value (with range 0 - 255), so just take one out of the packed integer and find out what percent of 255 it is:
int clr = (int) ((image.getRGB(x, y) & 0xFF) / 255.0 * 100);
System.out.println(clr);
getRGB returns all channels packed into one int so you shouldn't do arithmetic with it. Maybe use the norm of the RGB-vector instead?
for (int x = 0; x < image.getWidth(); ++x) {
for (int y = 0; y < image.getHeight(); ++y) {
final int rgb = image.getRGB(x, y);
final int red = ((rgb & 0xFF0000) >> 16);
final int green = ((rgb & 0x00FF00) >> 8);
final int blue = ((rgb & 0x0000FF) >> 0);
// Norm of RGB vector mapped to the unit interval.
final double intensity =
Math.sqrt(red * red + green * green + blue * blue)
/ Math.sqrt(3 * 255 * 255);
}
}
Note that there is also the java.awt.Color class that can be instantiated with the int returned by getRGB and provides getRed, getGreen and getBlue methods if you don't want to do the bit manipulations yourself.
I have an image that is stored as an array of pixel values. I want to be able to apply a brightness or contrast filter to this image. Is there any simple way, or algorithm, that I can use to achieve this.
Here is my code...
PlanarImage img=JAI.create("fileload","C:\\aimages\\blue_water.jpg");
BufferedImage image = img.getAsBufferedImage();
int w = image.getWidth();
int h = image.getHeight();
int k = 0;
int[] sbins = new int[256];
int[] pixel = new int[3];
Double d = 0.0;
Double d1;
for (int x = 0; x < bi.getWidth(); x++) {
for (int y = 0; y < bi.getHeight(); y++) {
pixel = bi.getRaster().getPixel(x, y, new int[3]);
k = (int) ((0.2125 * pixel[0]) + (0.7154 * pixel[1]) + (0.072 * pixel[2]));
sbins[k]++;
}
}
My suggestion would be to use the built-in methods of Java to adjust the brightness and contrast, rather than trying to adjust the pixel values yourself. It seems pretty easy by doing something like this...
float brightenFactor = 1.2f
PlanarImage img=JAI.create("fileload","C:\\aimages\\blue_water.jpg");
BufferedImage image = img.getAsBufferedImage();
RescaleOp op = new RescaleOp(brightenFactor, 0, null);
image = op.filter(image, image);
The float number is a percentage of the brightness. In my example it would increase the brightness to 120% of the existing value (ie. 20% brighter than the original image)
See this link for a similar question...
Adjust brightness and contrast of BufferedImage in Java
See this link for an example application...
http://www.java2s.com/Code/Java/Advanced-Graphics/BrightnessIncreaseDemo.htm