I will use this algorithm for image rotation, however I realized that it only rotates squares, not rectangles.
Would anyone know why?
Main code-problem:
public static int[] rotate(double angle, int[] pixels, int width, int height) {
final double radians = Math.toRadians(angle);
final double cos = Math.cos(radians);
final double sin = Math.sin(radians);
final int[] pixels2 = new int[pixels.length];
for(int pixel = 0; pixel < pixels2.length; pixel++) {
pixels2[pixel] = 0xFFFFFF;
}
for(int x = 0; x < width; x++) {
for(int y = 0; y < height; y++) {
final int centerx = width / 2;
final int centery = height / 2;
final int m = x - centerx;
final int n = y - centery;
final int j = ((int) ( m * cos + n * sin ) ) + centerx;
final int k = ((int) ( n * cos - m * sin ) ) + centery;
if( j >= 0 && j < width && k >= 0 && k < height ){
pixels2[ ( y * width + x ) ] = pixels[ ( k * width + j ) ];
}
}
}
return pixels2;
}
Context application:
try {
BufferedImage testrot = ImageIO.read(new File("./32x32.png"));
int[] linearpixels = new int[testrot.getWidth() * testrot.getHeight()];
int c = 0;
for(int i = 0; i < testrot.getWidth(); i++){
for(int j = 0; j < testrot.getHeight(); j++){
linearpixels[c] = testrot.getRGB(i, j);
c++;
}
}
int[] lintestrot = rotate(50, linearpixels, 32, 32);
BufferedImage image = new BufferedImage(70, 70, BufferedImage.TYPE_INT_RGB);
c = 0;
for(int i = 0; i < 32; i++){
for(int j = 0; j < 32; j++){
image.setRGB(i, j, lintestrot[c]);
c++;
}
}
File outputfile = new File("test002.bmp");
ImageIO.write(image, "bmp", outputfile);
} catch (IOException e1) {
e1.printStackTrace();
}
If you alter to 33 width or height the result will be wrong (wrong image).
You algorithm actually does work. The problem is with your loops in your context application. Because the pixels are stored in raster order, the outer loop needs to iterate to the height and the inner loop iterates to the width, e.g:
for(int i = 0; i < testrot.getHeight(); i++){
for(int j = 0; j < testrot.getWidth(); j++){
linearpixels[c] = testrot.getRGB(j, i); //edit here, tested
c++;
}
}
Then if you change height to 40 for example:
int[] lintestrot = rotate(50, linearpixels, 32, 40);
The loops need to change like this:
c = 0;
for(int i = 0; i < 40; i++){
for(int j = 0; j < 32; j++){
image.setRGB(i, j, lintestrot[c]);
c++;
}
}
Note that the order is reversed in the loops (height then width) compared to the function call (width then height).
Related
I want to pixelize a Image with JavaFx.
My problem is that I only have one written pixel in the end, so that it works for just one time.
i tried a
Here is my code:
Image img = imgView.getImage();
PixelReader pixelReader = img.getPixelReader();
WritableImage wImage = new WritableImage(
(int) img.getWidth(),
(int) img.getHeight());
PixelWriter pixelWriter = wImage.getPixelWriter();
for (int y = 1; y < img.getHeight(); y += 3) {
for (int x = 1; x < img.getWidth(); x += 3) {
Color px = pixelReader.getColor(x, y);
float red = (float) px.getRed();
float green = (float) px.getGreen();
float blue = (float) px.getBlue();
Color all = new Color(red / 3, green / 3, blue / 3, 1);
for (int u = 0; u <= 3; u++) {
for (int i = 0; i <= 3; i++) {
pixelWriter.setColor(u, i, all);
}
}
}
}
Just check the part where you set the color:
for (int u = 0; u <= 3; u++) {
for (int i = 0; i <= 3; i++) {
pixelWriter.setColor(u, i, all);
}
}
As you can see you always set the color of pixel at (0,0) - (3,3).
You need to use
pixelWriter.setColor(x + u, y + i, all);
However, you need to be sure that you won't try to set color of some pixels outside the image. Check the boundaries of loops by x, y, u and i.
I have to create an android app for image registration. I have created a 2D array for each image after cropping images and i made an fft using jtrasform, then i tryed to create a cross correlation matrix. serching in this matrix for the max value coordinates i expected to have the X e Y values for shifting my image but this values are wrong and i can't find the error.
public void Registration(Bitmap image,Bitmap image2) {
int square,x,y;
int Min2,Min1,Min;
Min1=min(image.getHeight(),image2.getHeight());
Min2=min(image.getWidth(),image2.getWidth());
if(Min1<Min2)
Min=Min1;
else
Min=Min2;
if (Min>1024)
square =1024;
else{
if (Min>512)
square =512;
else{
if (Min<256)
square=128;
else
square=256;
}}
Bitmap crop=Bitmap.createBitmap(image, 0,0,square, square);
Bitmap crop2=Bitmap.createBitmap(image2, 0,0,square, square);*/
float[][] array = new float[square-1][square-1];
float[][] array2 = new float[square-1][square-1];
float[][] array3 = new float[square-1][square-1];
for (x = 0; x < square-1; x++) {
int p = crop.getPixel(x,x);
int p1=crop2.getPixel(x,x);
array[x][x] = (Color.red(p) + Color.green(p) + Color.blue(p)) / 3;
array2[x][x] = (Color.red(p1) + Color.green(p1) + Color.blue(p1)) / 3;
}
for (y = square-1; y < (2*square)-1; y++) {
for (x = 0; x < square-1; x++){
array[x][y] = 0;
array2[x][y] = 0;
}}
FloatFFT_2D a = new FloatFFT_2D(square,square);
FloatFFT_2D b = new FloatFFT_2D(square,square);
a.complexForward(array);
b.complexForward(array2);
for (y = 0; y < (2*square)-1; y++) {
for (x = 0; x < square-1; x++){
if(y>=square){
array2[x][y] =-array2[x][y];}
array3[x][y]=array[x][y]*array2[x][y];}}
FloatFFT_2D c = new FloatFFT_2D(square-1,square-1);
c.complexInverse(array3,false);
Max(array3,(square),(2*square));
I need to edit the original instance variable private in[][] pixels; to be twice the width, I've done the algorithm to mirror the image and make a new array twice as wide I just don't know how to set the original int[][] pixels to it. The pixels array has to be the one modified, it can't go by another name.
private int[][] pixels;
...
if(transformationName == "Mirror"){
int[][] mirrorTemp = new int[height][width*2];
for(int h = 0; h < height; h++){
for(int w = 0; w < width; w++){
mirrorTemp[h][w] = pixels[h][w];
mirrorTemp[h][w + width] = pixels[h][width - h - 1];
}
}
int[][] pixels = new int[height][width*2];
for(int h = 0; h < height; h++){
for(int w = 0; w < (width*2); w++){
pixels[h][w] = mirrorTemp[h][w];
}
}
}
First, I believe the following is what you intended to do.
for(int h = 0; h < height; h++){
for(int w = 0; w < width; w++){
mirrorTemp[h][w] = pixels[h][w];
mirrorTemp[h][w + width] = pixels[h][width - w];
}
}
After this, you can simply
pixels = mirrorTemp;
since the two are both int[][] type.
Hope this helps.
I made two methods for a class called Picture, the name is self explanatory. The getAverageColor() method gets the average color of all the pixels in a certain area of the image specified by the parameters passed in. In the pixelate() method, it uses getAverageColor() to pixelate the image. The whole thing works, however it takes upwards of 2 minutes to pixelate a single image. It takes even longer if the pixelSize parameter is made smaller and the image is larger. So I was wondering if there is a better algorithm for doing this by manipulating the pixels.
/**
* NOTE: The smaller the pixelSize the longer the pixelation process takes
*/
public void pixelate(int pixelSize)
{
Pixel[][] pixels = this.getPixels2D();
int blockSize = pixelSize;
Color averageColor = null;
for(int row = 0; row < pixels.length; row += blockSize)
{
for (int col = 0; col < pixels[row].length; col += blockSize)
{
if (!((col + blockSize > pixels[0].length) || (row + blockSize > pixels.length)))
{
averageColor = getAverageColor(row, col, row+blockSize, col+blockSize);
}
for (int row_2 = row; (row_2 < row + blockSize) && (row_2 < pixels.length); row_2++)
{
for (int col_2 = col; (col_2 < col + blockSize) && (col_2 < pixels[0].length); col_2++)
{
pixels[row_2][col_2].setColor(averageColor);
}
}
}
}
}
public Color getAverageColor(int startRow, int startCol, int endRow, int endCol)
{
Pixel[][] pixels = this.getPixels2D();
Color averageColor = null;
int totalPixels = (endRow - startRow)*(endCol - startCol);
int totalRed = 0;
int averageRed = 0;
int totalGreen = 0;
int averageGreen = 0;
int totalBlue = 0;
int averageBlue = 0;
for (int row = startRow; row < endRow; row++)
{
for (int col = startCol; col < endCol; col++)
{
totalRed += pixels[row][col].getRed();
totalGreen += pixels[row][col].getGreen();
totalBlue += pixels[row][col].getBlue();
}
}
averageRed = totalRed / totalPixels;
averageGreen = totalGreen / totalPixels;
averageBlue = totalBlue / totalPixels;
averageColor = new Color(averageRed, averageGreen, averageBlue);
return averageColor;
}
I am currently making a game in Java and I am trying to draw an image on my screen, but nothing show up ( only a black screen but no errors ) :(
Here is the code to import the image:
public static Bitmap loadBitmap(String fileName) {
try {
BufferedImage img = ImageIO.read(Art.class.getResource(fileName));
int w = img.getWidth();
int h = img.getHeight();
Bitmap result = new Bitmap(w, h);
img.getRGB(0, 0, w, h, result.pixels, 0, w);
for (int I = 0; I < result.pixels.length; i++) {
int in = result.pixels[i];
int col = (in & 0xf) >> 2;
if (in == 0xffff00ff) col = -1;
result.pixels[i] = col;
}
return result;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
And the Bitmap class:
public void draw(Bitmap bitmap, int xOffs, int yOffs)
{
for(int y = 0; y < bitmap.height; y++)
{
int yPix = y + yOffs;
if(yPix < 0 || yPix >= height) continue;
for(int x = 0; x < bitmap.width; x++)
{
int xPix = x + xOffs;
if(xPix < 0 || xPix >= width) continue;
int alpha = bitmap.pixels[x + y * bitmap.width];
if(alpha > 0)
pixels[xPix + yPix * width] = bitmap.pixels[x + y * bitmap.width];
}
}
}
And to draw all of this :
public void render(Game game)
{
for(int y = 0; y < height; y++)
{
float yd = ((y + 0.5f) - height / 2.0f) / height;
if(yd < 0) yd *= -1;
float z = 10 / yd;
for(int x = 0; x < width; x++)
{
float xd = (x - width / 2.0f) / height;
xd *= z;
int xx = (int) (xd) & 7;
int yy = (int) (z + game.time * 0.1f) & 7;
pixels[x + y * width] = Art.floors.pixels[xx + yy * 64];
}
}
}
I have no errors! I don't really understand.. is this a bug caused by alpha or something? Ho and my image.png is 64x64 made in paint.net