I have an array representing the pixels of a grayscale image. I need an algorithm that can produce arrays of the same size that represent this image rotated at any angle, preferably without cropping any part of the image.
I've done some research and found various methods to flip images as well as some stuff on rotational matrices but I still don't have a good algorithm to do this.
Pretty simple for loop once you figure it out. If you are using a image processing library do tell because those solutions can be a lot faster.
//this function assumes a rectangular image,
// and rotates it 90 degrees right
public static Color[][] rotate(Color[][] image) {
Color[][] newImage = new Color[image[0].length][image.length];
for(int i = 0; i < image[0].length; i++) {
for(int j = 0; j < image.length; j++) {
newImage[i][j] = image[image.length-j-1][i];
}
}
return newImage;
}
Related
I want to convert this matrix into its original image that I have structured from.
I want to know the simplest way to do so.
int pixels[width][height]; //Filled with pixels of colored image(jpg)
i wonder how you going to manage color codes from int type.
Anyways, i think code will be like this. did not tested it
BufferedImage image;
for(int i=0; i<pixels.length; i++) {
for(int j=0; j<pixels[i].length; j++) {
int a = pixels[i][j];
Color newColor = new Color(R,G,B);
image.setRGB(j,i,newColor.getRGB());
}
}
Hope it helps
I want to generate a random terrain with OpenSimplexNoise. To start I just want to get a result and draw it to a window.
My question is now: How can I get the correct output of OpenSimplexNoise (cause there are many methods and I just don't know which is the correct one) and how to draw this result.
It should look like this:
public double[][] generateMap(long seed, int width, int height) {
double[][] map = new double[width][height];
// start generating things here, just how?
OpenSimplexNoise simplex = new OpenSimplexNoise(seed);
return map;
}
public void drawMap(double[][] map, Graphics g) {
for(int x = 0; x < map.length; x++) {
for(int y = 0; y < map[0].length; y++) {
Color color = new Color(); // how to get the color here?
}
}
}
This is the current code I've got.
Here is the link to OpenSimplexNoise for anyone who needs it:
https://gist.github.com/KdotJPG/b1270127455a94ac5d19
There's actually only 3 public methods - one for each for 2D, 3D & 4D noise.
Since you're filling a 2D array for your map , use the 2D noise eval method,
something like this:
for(int x=0; x<width; x++){
for(int y=0<y<height; y++){
map[x][y] = simplex.eval(x, y);
}
}
Later on, you can generate a color from the map values as follows:
Color color = Color.color(map[x][y], ma[x][y], map[x][y]);
The author also provides example usage code in OpenSimplexNoiseTest; he's using the 3D eval method, but always holding the z coord at zero. My guess is the example code was written before he added the 2D & 4D implementations. At any rate, it still works, but it might be a little slower than directly using 2D.
So after hours of searching I am ready to pull my hair out on this one.
I am doing some research in Computer Vision and am working with grayscale images. I need to end up with an "image" (a double scripted double array) of Sobel filtered double values. My Sobel converter is set up to take in a double scripted int array (int[][]) and go from there.
I am reading in a buffered image and I gather the grayscale int values via a method that I am 99% sure works perfectly (I can present it if need be).
Next I am attempting to convert this matrix of int values to a BufferedImage by the below method:
private BufferedImage getBIFromIntArr(int[][] matrix){
BufferedImage img = new BufferedImage(matrix.length * 4, matrix[0].length, BufferedImage.TYPE_INT_ARGB);
- Gather the pixels in the form of [alpha, r, g, b]
- multiply the size of the array by 4 for the model
int[] pixels = new int[(matrix.length * 4 * matrix[0].length)];
int index = 0;
for (int i = 0; i < matrix.length; i++) {
for (int j = 0; j < matrix[0].length; j++) {
int pixel = matrix[i][j];
pixels[index] = pixel;
index++;
for (int k = 0; k < 3; k++) {
pixels[index] = 0;
index++;
}
}
}
-get the raster
WritableRaster raster = img.getRaster();
-output the amount of pixels and a sample of the array
System.out.println(pixels.length);
for (int i = 0; i < pixels.length; i++) {
System.out.print(pixels[i] + " ");
}
- set the pixels of the raster
raster.setPixels(0, 0, matrix.length, matrix[0].length, pixels);
- paint the image via an external routing to check works (does not)
p.panel.setNewImage(img);
return img;
}
Here is my understanding. The ARGB Type consists of 4 values Alpha, Red, Green, and Blue. I am guessing that setting the alpha values in the new BufferedImage to the greyscale image int values (the matrix values passed in) then this will reproduce the image. Please correct me if I am wrong. So as you can see I create an array of pixels that stores the int values like this: [intValue, 0, 0, 0] repeatedly to try to stay with the 4 value model.
Then I create a writable raster and set the gathered pixels in it using the gathered pixels. The only thing is that I get nothing in the BufferedImage. No error with the code below and Im sure my indeces are correct.
What am I doing wrong? Im sure it is obvious but any help is appreciated because I cant see it. Perhaps my assumption about the model is wrong?
Thanks,
Chronic
I am making a game. It is a 2D game, and the map is drawn by a double loop like this:
for(int i = 0; i < mapArray.length; i++){
for(int j = 0; j < mapArray[1].length; j++){
//if statement for if its on the screen
g.drawImage(tiles.get(mapArray[i][j]).getImage(), j * textureSize, i * textureSize, null);
}
}
They are 32x32 images, and I was wondering stitching them all together to create one large image at the beginning would be more efficient in drawing. The resulting image would only be around 1500x1500.
I was thinking of making it stitched into one image (Especially since I am planning on making the images smaller which would make the loop need ever more time.) so that it didn't have to run through the double for loop every time it renders (shooting for 60 FPS). But I don't know how to do this, and would it actually improve the performance if I did?
Also, I could just stitch them into rows, and only render the rows that are on the screen(to remove the large image problem) So it would still be much less intensive than that crazy loop I've got right now.
Edit: And one last thing, if you can provide an example of how to do this without extra libraries that would be optimal.
I currently have this code for stitching:
Edit: now works. Leaving this here for future readers:
public void stitchImages(){
BufferedImage temp = new BufferedImage( <Width> , <height> , BufferedImage.TYPE_INT_RGB);
Graphics2D g = (Graphics2D) temp.getGraphics();
for (int b = 0; b < mapArray.length; b++) {
for (int a = 0; a < mapArray[b].length; a++) {
g.drawImage(tiles.get(mapArray[b][a]).getImage(),
(int) mapX + a * textureSize, (int) mapY + b
* textureSize, null);
}
}
mapImage = temp;
}
Create a new Image to encapsulate all of your images. Draw your images when you load up, then just draw that in paintComponent()
BufferedImage im = new BufferedImage(1500,1500,BufferedImage.TYPE_INT_RGB);
private void init() {
Graphics g = im.getGraphics();
for(int i = 0; i < mapArray.length; i++){
for(int j = 0; j < mapArray[1].length; j++){
//if statement for if its on the screen
g.drawImage(tiles.get(mapArray[i][j]).getImage(), j * textureSize, i * textureSize, null);
}
}
}
public void paintCompoent(Graphics g) {
super.paintComponent(g);
g.drawImage(im,0,0,null);
}
EDIT:
As for your idea about just painting the lines that are on the screen, you can do that by creating an Image the size of the window and just drawing to that. But in general, it's not a big problem to paint a big Image (as long as the Image fits in memory and you don't get an OutOfMemoryException) as your GPU's capabilities smoke your CPU's
I have an array called image[][] and i want to create a BufferedImage out of this so I can have the player store it in a file.
// Initialize Color[][] however you were already doing so.
Color[][] image;
// Initialize BufferedImage, assuming Color[][] is already properly populated.
BufferedImage bufferedImage = new BufferedImage(image.length, image[0].length,
BufferedImage.TYPE_INT_RGB);
// Set each pixel of the BufferedImage to the color from the Color[][].
for (int x = 0; x < image.length; x++) {
for (int y = 0; y < image[x].length; y++) {
bufferedImage.setRGB(x, y, image[x][y].getRGB());
}
}
This is a straightforward way of creating (and potentially storing) an image, if that's what you're trying to get at. However, this is not efficient by any means. Try it with a larger image and you'll see a noticeable speed difference.