I'm trying to get this code to run, but I keep getting an error saying:
at main.Main.flipVertically(Main.java:403) which is the code below.
img[row][col] = img[height - row - 1][col];
I don't know what's wrong with the code or the error they are talking about.
Here's the rest of the code:
public static int[][] flipVertically(int[][] img) {
String dir = "image.jpg";
img = Util.readImageToMatrix(dir);
int height = img[0].length;
int width = img.length;
for(int row = 0; row < height/2; row++)
{
for(int col = 0; col < width; col++)
{
int p = img[row][col];
img[row][col] = img[height - row - 1][col];
img[height - row - 1][col] = p;
}
}
return img;
}
height and width swapped
int height = img.length;
int width = img[0].length;
you souldnt read the matrix in the loop and use the parameter img from function input, or better create a new matrix.
you can swap entire rows like:
public static void flipVertically(int[][] img) {
int height = img.length;
int width = img[0].length;
for(int row = 0; row < height/2; row++)
{
int [] myrow = img[row];
img [row] = img[height - row - 1];
img[height - row - 1] = myrow;
}
}
Related
I have a class to separate and join image in tiles. It works fine when the sides of the tile correspond to the dimensions of the image, i.e. height 250, tile height 25. But when it's not it doesn't create smaller tiles at the borders as it should.
Where would be the problem to properly create the border tiles smaller than the rest?
Constructor:
public EdgeBufferedImage(BufferedImage image, int w, int h){
this.sourceImg = image;
this.setCol((int)Math.ceil(image.getWidth()/(double)w));
this.setRow((int)Math.ceil(image.getHeight()/(double)h));
this.setWidth(image.getWidth());
this.setHeight(image.getHeight());
this.setTilew(w);
this.setTileh(h);
this.setMatImg(new BufferedImage[row][col]);
}
Methods:
Image tiling
public void createSmallImages() {
int rows = getRow();
int columns = getCol();
int smallWidth = getTilew();
int smallHeight = getTileh();
for (int i = 0; i < rows; i++) {
for (int j = 0; j < columns; j++) {
if (j == columns - 1) smallWidth = getWidth() - (getTilew() * j);
if (i == rows - 1) smallHeight = getHeight() - (getTileh() * i);
matImg[i][j] = getSourceImg().getSubimage(j * smallWidth, i
* smallHeight, smallWidth, smallHeight);
}
smallWidth = getTilew();
smallHeight = getTileh();
}
}
Image joining
public void joinTiles(){
int rows = getRow();
int columns = getCol();
int smallWidth = getTilew();
int smallHeight = getTileh();
BufferedImage comb = new BufferedImage(getWidth(), getHeight(), BufferedImage.TYPE_INT_RGB);
Graphics2D g = (Graphics2D) comb.getGraphics();
g.setColor(Color.RED);
for (int row = 0; row < rows; row++){
for (int col = 0; col < columns; col++){
BufferedImage piece = getMatImg()[row][col];
if (col == columns - 1) smallWidth = getWidth() - (getTilew() * col);
if (row == rows - 1) smallHeight = getHeight() - (getTileh() * row);
g.drawImage(piece, col * smallWidth, row * smallHeight, smallWidth, smallHeight, null);
g.drawRect(col * smallWidth, row * smallHeight, smallWidth, smallHeight);
}
smallWidth = getTilew();
smallHeight = getTileh();
}
g.dispose();
setSourceImg(comb);
}
Original image is 512*512
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;
}
BufferedImage image = ImageIO.read(new File(img path));
int width = image.getWidth();
int height = image.getHeight();
int[][] result = new int[height][width];
for (int row = 0; row < height; row++) {
for (int col = 0; col < width; col++) {
result[row][col] = image.getRGB(row, col);
}
}
and this is the exception I get :
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: Coordinate out of bounds!
at sun.awt.image.ByteInterleavedRaster.getDataElements(ByteInterleavedRaster.java:301)
at java.awt.image.BufferedImage.getRGB(BufferedImage.java:871)
at PlantExtraction.main(PlantExtraction.java:46)
How can I remove these exceptions ?
The code
image.getRGB(row, col);
Should be
image.getRGB(col, row);
As the documentation says:
getRGB(int x, int y).
Documentation
(your col value is running upto width - which is the x-maximum of the image, so use col for x and row for y)
i´m trying to convert a image into a matrix and convert it back, but the 2 pictures are different:
convert it into a matrix:
public int[][] getMatrixOfImage(BufferedImage bufferedImage) {
int width = bufferedImage.getWidth(null);
int height = bufferedImage.getHeight(null);
int[][] pixels = new int[width][height];
for (int i = 0; i < width; i++) {
for (int j = 0; j < height; j++) {
pixels[i][j] = bufferedImage.getRGB(i, j);
}
}
return pixels;
}
and convert it back into a bufferedImage:
public BufferedImage matrixToBufferedImage(int[][] matrix) {
int width=matrix[0].length;
int height=matrix.length;
BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB_PRE);
for (int i = 0; i < matrix.length; i++) {
for (int j = 0; j < matrix[0].length; j++) {
int pixel=matrix[i][j] <<24|matrix[i][j] <<16|matrix[i][j]<<8|matrix[i][j] ;
bufferedImage.setRGB(i, j, pixel);
}
}
return bufferedImage;
}
with this result:
http://img59.imageshack.us/img59/5464/mt8a.png
Thanks!
Why do you do
int pixel=matrix[i][j] <<24|matrix[i][j] <<16|matrix[i][j]<<8|matrix[i][j];
instead of just
int pixel=matrix[i][j];
?
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());
}
}
}
}