OK. so let's say I have this picture: http://i.stack.imgur.com/oYhJy.png
I'm trying to do a crop (which works -- I just have the wrong numbers) of the image into separate image arrays. The tile image (linked above) is 36 tiles wide and 15 tiles long. So that's 1152 pixels in width (32 tile width * 36 tiles) and 480 pixels in height (32 tile height * 15 tiles).
Here's what I have so far:
for (int xi = 0; xi < 522; xi++) {
int cropHeight = 32;
int cropWidth = 32;
int cropStartX = xi*32;
int cropStartY = 0;
if (xi % 36 == 0) {
cropStartY = xi*32;
}
BufferedImage processedImage = cropMyImage(originalImage, cropWidth, cropHeight, cropStartX, cropStartY);
tiles[xi] = processedImage;
}
What am I doing wrong? It's working technically, but it's getting the wrong tile images.
Probably clearer if you did a double loop rather than trying to use modulus.
int i = 0;
// no need to have these values inside a loop. They are constants.
int cropHeight = 32;
int cropWidth = 32;
for (int x = 0; x < 36; x++) {
for (int y = 0; y < 15; y++) {
int cropStartX = x*32;
int cropStartY = y*32;
BufferedImage processedImage = cropMyImage(originalImage, cropWidth, cropHeight, cropStartX, cropStartY);
tiles[i++] = processedImage;
}
}
Probably should be:
int cropStartX = (xi%36)*32;
int cropStartY = xi/36*32;
Related
I'm creating a method that takes two parameters with 2 indexes a start and an end that takes a location of the picture being edited and turn those pixels to a different color. Using a while loop to index start and end.
The problem I'm having is I'm only a getting a really small portion to change color:
Don't mind some of the code that is commented out. I was trying a bunch of different things.
public void negative(int start, int end)
{
Pixel[] pixelArray = this.getPixels(); //pixelarray index
Pixel pixel = null;
// int height = this.getHeight();
//int paintPoint = height / 2;
//int width = this.getWidth();
int i = 0;
int red, green, blue = 0;
// int x = 0;
Pixel topPixel = null;
Pixel bottomPixel = null;
//int startY;
//int startX;
int y = start;
int x = end;
//int count;
while( y < this.getHeight())
{
y++;
while (x < this.getWidth()) //loops through index
{
pixel = this.getPixel(x,y);
red = pixel.getRed();
green = pixel.getGreen();//collects color green
blue = pixel.getBlue();//collects color blue
Color negColor = new Color( 255 - red, 255 - green, 255 - blue);//sets new values of pixels
pixel.setColor(negColor);
x++;
//count = count + 1;
i++;//indexes continuing
}
}
}
A picture is 2D yet you are treating it as 1D (notice after once through your inner x loop it never is reset to its min value). If you wish to color an arbitrary rectangle within a given photo the parms should include two points : minx, miny and maxx maxy then your pair of 2D loops visits each point in that region line by line.
// do sanity checks on your parms
if (this.getWidth() < maxx) {
maxx = this.getWidth();
}
if (this.getHeight() < maxy) {
maxy = this.getHeight();
}
if (minx < 0) {
minx = 0;
}
if (miny < 0) {
miny = 0;
}
for (y = mixy; y < maxy; y++) {
for (x = mixx; x < maxx; x++) {
// now your have valid x and y values
}
}
I have a matrix double[][] with arbitrary dimensions but bigger than 300 (maybe in one or maybe on both dimensions). I want to scale it to double[300][300].
My main approach is to interpolate the matrix and bring it up to double[600][600] and then take four elements and find their average, i.e. the elements 0,0, 0,1, 1,0 and 1,1 will be the 0,0 of the final 300x300 matrix.
I have found the interpolation library in JAVA but I cannot figure out how to use it. Can anyone provide some examples or info?
The library is: http://docs.oracle.com/cd/E17802_01/products/products/java-media/jai/forDevelopers/jai-apidocs/javax/media/jai/Interpolation.html
Thnx.
What about writing a simple method that maps source cells to destination, then averages out?
public static boolean matrixReduce(double[][] dst, double[][] src) {
double dstMaxX = dst.length - 1, dstMaxY = dst[0].length - 1;
double srcMaxX = src.length - 1, srcMaxY = src[0].length - 1;
int count[][] = new int[dst.length][dst[0].length];
for (int x = 0; x < src.length; x++) {
for (int y = 0; y < src[0].length; y++) {
int xx = (int) Math.round((double) x * dstMaxX / srcMaxX);
int yy = (int) Math.round((double) y * dstMaxY / srcMaxY);
dst[xx][yy] += src[x][y];
count[xx][yy]++;
}
}
for (int x = 0; x < dst.length; x++) {
for (int y = 0; y < dst[0].length; y++) {
dst[x][y] /= count[x][y];
}
}
return true;
}
I know how to get the RGB values of individual pixels of a bitmap. How can I get the average RGB value for all of the pixels of a bitmap?
I think below code for exact answer to you.
Get the Average(Number of pixels)of Red, Green and Blue value for the given bitmap.
Bitmap bitmap = someBitmap; //assign your bitmap here
int redColors = 0;
int greenColors = 0;
int blueColors = 0;
int pixelCount = 0;
for (int y = 0; y < bitmap.getHeight(); y++)
{
for (int x = 0; x < bitmap.getWidth(); x++)
{
int c = bitmap.getPixel(x, y);
pixelCount++;
redColors += Color.red(c);
greenColors += Color.green(c);
blueColors += Color.blue(c);
}
}
// calculate average of bitmap r,g,b values
int red = (redColors/pixelCount);
int green = (greenColors/pixelCount);
int blue = (blueColors/pixelCount);
The answer from john sakthi does not work correctly if the Bitmap has transparency (PNGs). I modified the answer for correctly getting the red/green/blue averages while accounting for transparent pixels:
/**
* Calculate the average red, green, blue color values of a bitmap
*
* #param bitmap
* a {#link Bitmap}
* #return
*/
public static int[] getAverageColorRGB(Bitmap bitmap) {
final int width = bitmap.getWidth();
final int height = bitmap.getHeight();
int size = width * height;
int pixelColor;
int r, g, b;
r = g = b = 0;
for (int x = 0; x < width; ++x) {
for (int y = 0; y < height; ++y) {
pixelColor = bitmap.getPixel(x, y);
if (pixelColor == 0) {
size--;
continue;
}
r += Color.red(pixelColor);
g += Color.green(pixelColor);
b += Color.blue(pixelColor);
}
}
r /= size;
g /= size;
b /= size;
return new int[] {
r, g, b
};
}
you can use this method for this purpose: Bitmap.createBitmap
For instance:
int[] colors = new int[yourWidth * yourHeight];
Arrays.fill(colors, Color.Black);
Bitmap bitamp = Bitamp.createBitmap(colors, yourWidth, yourHeight, Bitmap.Config.ARGB_8888);
Check for typo
I'm having trouble getting my method to work. The method should mirror any image I choose on its diagonal to produce a mirror effect, but at the moment it just produces the same image unedited and I don't what I'm doing wrong. Any help would be greatly appreciated. Thank you.
public Picture mirrorImageDiagonal() {
int size = this.getWidth();
Pixel rightPixel = null;
Pixel leftTargetPixel = null;
Pixel rightTargetPixel = null;
Picture target = new Picture(size, size);
for (double x = 0; x < size; x ++) {
for (double y = 0; y <= x; y ++) {
int yIndex = Math.min((int) y, this.getHeight() - 1);
int xIndex = Math.min((int) x, this.getWidth() - 1);
leftTargetPixel = target.getPixel(yIndex, xIndex);
rightTargetPixel = target.getPixel(xIndex, yIndex);
rightPixel = this.getPixel(xIndex, yIndex);
rightTargetPixel.setColor(rightPixel.getColor());
leftTargetPixel.setColor(rightPixel.getColor());
}
}
return target;
}
I am assuming that you are trying to complete the challenge for A6 in the picture lab packet. I just completed this for school, but if you are not, I hope this still helps you.
public void mirrorDiagonal()
{
Pixel[][] pixels = this.getPixels2D();
Pixel pixel1 = null;
Pixel pixel2 = null;
int width = pixels[0].length;
for (int row = 0; row < pixels.length; row++)
{
for (int col = 0; col < width; col++)
{
if (col < pixels.length)
{
pixel1 = pixels[row][col];
pixel2 = pixels[col][row];
pixel1.setColor(pixel2.getColor());
}
}
}
}
This method sets the pixel color from one image to the other. How can i set the pixels from the imgPix array to the screen.pixels array so that the image appears larger on the screen.pixels array? I dumbed down the code to make the concept easy to understand.
public void drawSprite(Screen screen)
{
for(int y = 0; y < 16; y++)
{
for(int x = 0; x < 16; x++)
{
screen.pixels[x + y * screen.WIDTH] = this.imgPix[x + y * this.WIDTH];
}
}
}
A nice little trick that i discover is to cast to an int. this rounds down the number repeating the pattern..
// scale = 2
-------------y = 0,1,2,3,4,5,6,7,8,9 // as y increase.. y++
(int) y/scale = 0,0,1,1,2,2,3,3,4,4
//
// out of 10 numbers 5 were drawn this is scaling up
// As you can see from the above as y increase y/scale repeats with a the correct pattern
// this happends because casting the (int) rounds down.
//
// scale = 0.8
-------------y = 0,1,2,3,4,5,6,7,8,9
(int) y/scale = 0,1,2,3,5,6,7,8,10,11
//
// out of 10 numbers 2 were skipped this is scaling down an image
public void drawSprite(Screen screen,Image image,float scale)
{
for(int y = 0; y < image.height*scale; y++)
{
int scaleY = (int)(y/scale);
for(int x = 0; x < image.width*scale; x++)
{
int scaleX = (int)(x/scale);
screen.pixels[x + y * screen.WIDTH] = image.pixels[scaleX + scaleY * image.width];
}
}
}
I've answered this question before on programmers.stackexchange.com (similar enough to java to be relevant):
https://softwareengineering.stackexchange.com/questions/148123/what-is-the-algorithm-to-copy-a-region-of-one-bitmap-into-a-region-in-another/148153#148153
--
struct {
bitmap bmp;
float x, y, width, height;
} xfer_param;
scaled_xfer(xfer_param src, xfer_param det)
{
float src_dx = dst.width / src.width;
float src_dy = dst.height / src.height;
float src_maxx = src.x + src.width;
float src_maxy = src.y + src.height;
float dst_maxx = dst.x + dst.width;
float dst_maxy = dst.y + dst.height;
float src_cury = src.y;
for (float y = dst.y; y < dst_maxy; y++)
{
float src_curx = src.x;
for (float x = dst.x; x < dst_maxx; x++)
{
// Point sampling - you can also impl as bilinear or other
dst.bmp[x,y] = src.bmp[src_curx, src_cury];
src_curx += src_dx;
}
src_cury += src_dy;
}
}