How to fix java.lang.ArrayIndexOutOfBoundsException image resizing error? - java
I have little experience with java programming, but I know my way around it a little. I want to pick up a project that was left behind by someone else. I was doing well fixing other errors here and there, but this one stumped me. Here it is:
javax.imageio.IIOException: Can't read input file!
at javax.imageio.ImageIO.read(Unknown Source)
at Replacer.main(Replacer.java:19)
To my surprise, the program still opened. However, when I tried to open a picture, this happened, and displayed a picture of 0 x 0 pixels:
Exception in thread "AWT-EventQueue-0" java.lang.ArrayIndexOutOfBoundsException:
2147483647
at ImageEditor.resize(ImageEditor.java:384)
at ImageEditor.resize(ImageEditor.java:308)
at ImageFrame.setImage(ImageFrame.java:438)
at ImageFrame.actionPerformed(ImageFrame.java:765)
at java.awt.Button.processActionEvent(Unknown Source)
at java.awt.Button.processEvent(Unknown Source)
at java.awt.Component.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
at java.awt.EventQueue.access$500(Unknown Source)
at java.awt.EventQueue$3.run(Unknown Source)
at java.awt.EventQueue$3.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionP
rivilege(Unknown Source)
at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionP
rivilege(Unknown Source)
at java.awt.EventQueue$4.run(Unknown Source)
at java.awt.EventQueue$4.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionP
rivilege(Unknown Source)
at java.awt.EventQueue.dispatchEvent(Unknown Source)
at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.run(Unknown Source)
Replacer:
import java.awt.Color;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.PrintStream;
import javax.imageio.ImageIO;
public class Replacer
{
public static void main(String[] args)
{
BufferedImage i = null;
BufferedImage i2 = null;
Color[][] blockColors = new Color[16][16];
ImageFrame b = new ImageFrame(i);
try
{
i2 = ImageIO.read(new File("terrain.png"));
int blockSize = i2.getWidth(b) / 16;
System.out.println("Analyzing terrain.png");
int[] buffer = ImageEditor.returnBuffer(i2, b);
int width = i2.getWidth(b);
for (int j = 0; j < 16; j++) {
for (int k = 0; k < 16; k++) {
if ((j <= 2) || (k <= 8))
{
int[] i3 = ImageEditor.crop(buffer, width, width, b, j * blockSize, k * blockSize, blockSize, blockSize);
blockColors[j][k] = ImageEditor.getAverageColor(i3, b);
}
}
}
Color[] c2 = new Color[100];
c2[0] = blockColors[1][8];
c2[1] = blockColors[2][10];
c2[2] = blockColors[1][11];
c2[3] = blockColors[1][9];
c2[4] = blockColors[1][7];
c2[5] = blockColors[0][4];
c2[6] = blockColors[2][13];
c2[7] = blockColors[1][13];
c2[8] = blockColors[1][12];
c2[9] = blockColors[2][7];
c2[10] = blockColors[2][11];
c2[11] = blockColors[2][8];
c2[12] = blockColors[2][9];
c2[13] = blockColors[2][12];
c2[14] = blockColors[1][14];
c2[15] = blockColors[1][10];
c2[16] = blockColors[1][0];
c2[17] = blockColors[2][0];
c2[18] = blockColors[2][1];
c2[19] = blockColors[3][1];
c2[20] = blockColors[8][4];
c2[21] = blockColors[5][2];
c2[22] = blockColors[4][2];
c2[23] = blockColors[6][7];
c2[24] = blockColors[4][0];
c2[25] = blockColors[0][1];
c2[26] = blockColors[0][11];
c2[27] = blockColors[7][0];
c2[28] = blockColors[6][1];
c2[29] = blockColors[7][1];
c2[30] = blockColors[8][1];
c2[31] = blockColors[0][9];
c2[32] = blockColors[10][4];
c2[33] = blockColors[9][6];
c2[34] = blockColors[7][6];
c2[35] = blockColors[8][6];
c2[36] = blockColors[2][4];
c2[37] = blockColors[6][3];
c2[38] = blockColors[1][1];
c2[39] = blockColors[5][1];
c2[40] = blockColors[4][1];
c2[41] = blockColors[4][7];
c2[42] = blockColors[5][7];
c2[43] = blockColors[0][3];
c2[44] = blockColors[3][4];
c2[45] = blockColors[8][8];
c2[46] = blockColors[8][9];
c2[47] = blockColors[8][10];
c2[48] = blockColors[8][11];
c2[49] = blockColors[8][12];
for (int j = 0; j < c2.length / 2; j++)
{
double shadowRed = 0.892D * c2[j].getRed() + 0.5D;
double shadowGreen = 0.892D * c2[j].getGreen() + 0.5D;
double shadowBlue = 0.892D * c2[j].getBlue() + 0.5D;
c2[(50 + j)] = new Color((int)shadowRed, (int)shadowGreen, (int)shadowBlue);
}
for (int j = 0; j < c2.length; j++) {
System.out.println("colors[" + j + "] = new Color(" + c2[j].getRed() + "," + c2[j].getGreen() + "," + c2[j].getBlue() + ");");
}
b.setColors(c2);
System.out.println("Done");
}
catch (Exception e)
{
e.printStackTrace();
}
b.repaint();
}
}
ImageEditor:
import java.awt.Color;
import java.awt.Component;
import java.awt.Image;
import java.awt.MediaTracker;
import java.awt.image.MemoryImageSource;
import java.awt.image.PixelGrabber;
import java.io.PrintStream;
public class ImageEditor
{
public static int[] returnBuffer(Image i, Component c)
{
MediaTracker tracker = new MediaTracker(c);
tracker.addImage(i, 0);
try
{
tracker.waitForAll();
}
catch (Exception e)
{
System.out.println("Image loading interrupted");
}
int width = i.getWidth(c);
int height = i.getHeight(c);
int[] buffer = new int[width * height];
PixelGrabber grabber = new PixelGrabber(i, 0, 0, width, height, buffer, 0, width);
try
{
grabber.grabPixels();
}
catch (InterruptedException e)
{
e.printStackTrace();
}
return buffer;
}
public static Image simplifyColors(int width, int height, int[] buffer, Component c, Color[] colors)
{
double[] w = new double[colors.length];
for (int k = 0; k < w.length; k++) {
w[k] = 1.0D;
}
return simplifyColors(width, height, buffer, c, colors, w);
}
public static Image simplifyColors(int width, int height, int[] buffer, Component c, Color[] colors, double[] weights)
{
int[] simple = new int[buffer.length];
for (int j = 0; j < buffer.length; j++)
{
int minDiff = 10000000;
Color current = new Color(buffer[j], true);
Color col = Color.black;
for (int k = 0; k < colors.length; k++)
{
Color test = colors[k];
double w = weights[k];
if (test != null)
{
int diff = (int)((Math.pow(test.getRed() - current.getRed(), 2.0D) + Math.pow(test.getGreen() - current.getGreen(), 2.0D) + Math.pow(test.getBlue() - current.getBlue(), 2.0D)) / w);
if (diff < minDiff)
{
col = test;
minDiff = diff;
}
}
}
if (current.getAlpha() >= 128) {
simple[j] = col.getRGB();
} else {
simple[j] = new Color(255, 255, 255, 0).getRGB();
}
}
return c.createImage(new MemoryImageSource(width, height, simple, 0, width));
}
public static Image simplifyColors2(Image i, int[] buffer, Component c, Color[] colors)
{
double[] w = new double[colors.length];
for (int k = 0; k < w.length; k++) {
w[k] = 1.0D;
}
return simplifyColors2(i, buffer, c, colors, w);
}
public static Image simplifyColors2(Image i, int[] buffer, Component c, Color[] colors, double[] weights)
{
int height = i.getHeight(c);
int width = i.getWidth(c);
int[] simple = new int[buffer.length];
float[] hsb1 = new float[3];
float[] hsb2 = new float[3];
for (int j = 0; j < buffer.length; j++)
{
int minDiff = 10000000;
Color current = new Color(buffer[j], true);
hsb1 = Color.RGBtoHSB(current.getRed(), current.getGreen(), current.getBlue(), null);
Color col = Color.black;
for (int k = 0; k < colors.length; k++)
{
Color test = colors[k];
if (test != null)
{
hsb2 = Color.RGBtoHSB(test.getRed(), test.getGreen(), test.getBlue(), null);
int diff = (int)(Math.pow(hsb1[0] - hsb2[0], 2.0D) + Math.pow(hsb1[1] - hsb2[1], 2.0D) + Math.pow(hsb1[2] - hsb2[2], 2.0D));
if (diff < minDiff)
{
col = test;
minDiff = diff;
}
}
}
if (current.getAlpha() >= 128) {
simple[j] = col.getRGB();
} else {
simple[j] = new Color(255, 255, 255, 0).getRGB();
}
}
return c.createImage(new MemoryImageSource(width, height, simple, 0, width));
}
public static Image simplifyColors3(int width, int height, int[] buffer2, Component c, Color[] colors, double[] weights)
{
int[] buffer = (int[])buffer2.clone();
int[] simple = new int[buffer.length];
for (int j = 0; j < buffer.length; j++)
{
int minDiff = 10000000;
Color current = new Color(buffer[j], true);
Color col = Color.black;
for (int k = 0; k < colors.length; k++)
{
if (current.getAlpha() == 0)
{
col = new Color(255, 255, 255, 0);
break;
}
Color test = colors[k];
double w = weights[k];
if (test != null)
{
int diff = (int)((Math.pow(test.getRed() - current.getRed(), 2.0D) + Math.pow(test.getGreen() - current.getGreen(), 2.0D) + Math.pow(test.getBlue() - current.getBlue(), 2.0D)) / w);
if (diff < minDiff)
{
col = test;
minDiff = diff;
}
}
}
int quantErrorR = current.getRed() - col.getRed();
int quantErrorG = current.getGreen() - col.getGreen();
int quantErrorB = current.getBlue() - col.getBlue();
if ((j + 1) % width != 0)
{
Color x = new Color(buffer[(j + 1)], true);
Color y = new Color(Math.max(0, Math.min(x.getRed() + col.getAlpha() / 255 * quantErrorR * 7 / 16, 255)), Math.max(0, Math.min(x.getGreen() + col.getAlpha() / 255 * quantErrorG * 7 / 16, 255)), Math.max(0, Math.min(x.getBlue() + col.getAlpha() / 255 * quantErrorB * 7 / 16, 255)), x.getAlpha());
buffer[(j + 1)] = y.getRGB();
}
if (((j - 1) % width != 0) && (j - 1 + width < buffer.length))
{
Color x = new Color(buffer[(j - 1 + width)], true);
Color y = new Color(Math.max(0, Math.min(x.getRed() + col.getAlpha() / 255 * quantErrorR * 3 / 16, 255)), Math.max(0, Math.min(x.getGreen() + col.getAlpha() / 255 * quantErrorG * 3 / 16, 255)), Math.max(0, Math.min(x.getBlue() + col.getAlpha() / 255 * quantErrorB * 3 / 16, 255)), x.getAlpha());
buffer[(j - 1 + width)] = y.getRGB();
}
if (j + width < buffer.length)
{
Color x = new Color(buffer[(j + width)], true);
Color y = new Color(Math.max(0, Math.min(x.getRed() + col.getAlpha() / 255 * quantErrorR * 5 / 16, 255)), Math.max(0, Math.min(x.getGreen() + col.getAlpha() / 255 * quantErrorG * 5 / 16, 255)), Math.max(0, Math.min(x.getBlue() + col.getAlpha() / 255 * quantErrorB * 5 / 16, 255)), x.getAlpha());
buffer[(j + width)] = y.getRGB();
}
if (((j + 1) % width != 0) && (j + 1 + width < buffer.length))
{
Color x = new Color(buffer[(j + 1 + width)], true);
Color y = new Color(Math.max(0, Math.min(x.getRed() + col.getAlpha() / 255 * quantErrorR * 1 / 16, 255)), Math.max(0, Math.min(x.getGreen() + col.getAlpha() / 255 * quantErrorG * 1 / 16, 255)), Math.max(0, Math.min(x.getBlue() + col.getAlpha() / 255 * quantErrorB * 1 / 16, 255)), x.getAlpha());
buffer[(j + 1 + width)] = y.getRGB();
}
if (current.getAlpha() >= 128) {
simple[j] = col.getRGB();
} else {
simple[j] = new Color(255, 255, 255, 0).getRGB();
}
}
return c.createImage(new MemoryImageSource(width, height, simple, 0, width));
}
public static Image shadowColors(int width, int height, int[] buffer, Component c, Color[] colors, double[] weights)
{
int[] simple = new int[buffer.length];
double k2 = 0.0D;
for (int j = 0; j < buffer.length; j++)
{
int minDiff = 10000000;
Color current = new Color(buffer[j], true);
Color col = Color.black;
for (int k = 0; k < colors.length; k++)
{
Color test = colors[k];
double w = weights[k];
if (test != null)
{
int diff = (int)((Math.pow(test.getRed() - current.getRed(), 2.0D) + Math.pow(test.getGreen() - current.getGreen(), 2.0D) + Math.pow(test.getBlue() - current.getBlue(), 2.0D)) / w);
if (diff < minDiff)
{
col = test;
k2 = k;
minDiff = diff;
}
}
}
if (current.getAlpha() >= 128)
{
if (k2 < colors.length / 2) {
simple[j] = Color.WHITE.getRGB();
} else {
simple[j] = Color.BLACK.getRGB();
}
}
else {
simple[j] = new Color(255, 255, 255, 0).getRGB();
}
}
return c.createImage(new MemoryImageSource(width, height, simple, 0, width));
}
public static Image shadowColors3(int width, int height, int[] buffer2, Component c, Color[] colors, double[] weights)
{
int[] buffer = (int[])buffer2.clone();
int[] simple = new int[buffer.length];
double k2 = 0.0D;
for (int j = 0; j < buffer.length; j++)
{
int minDiff = 10000000;
Color current = new Color(buffer[j], true);
Color col = Color.black;
for (int k = 0; k < colors.length; k++)
{
if (current.getAlpha() == 0)
{
col = new Color(255, 255, 255, 0);
break;
}
Color test = colors[k];
double w = weights[k];
if (test != null)
{
int diff = (int)((Math.pow(test.getRed() - current.getRed(), 2.0D) + Math.pow(test.getGreen() - current.getGreen(), 2.0D) + Math.pow(test.getBlue() - current.getBlue(), 2.0D)) / w);
if (diff < minDiff)
{
col = test;
minDiff = diff;
k2 = k;
}
}
}
int quantErrorR = current.getRed() - col.getRed();
int quantErrorG = current.getGreen() - col.getGreen();
int quantErrorB = current.getBlue() - col.getBlue();
if ((j + 1) % width != 0)
{
Color x = new Color(buffer[(j + 1)], true);
Color y = new Color(Math.max(0, Math.min(x.getRed() + col.getAlpha() / 255 * quantErrorR * 7 / 16, 255)), Math.max(0, Math.min(x.getGreen() + col.getAlpha() / 255 * quantErrorG * 7 / 16, 255)), Math.max(0, Math.min(x.getBlue() + col.getAlpha() / 255 * quantErrorB * 7 / 16, 255)), x.getAlpha());
buffer[(j + 1)] = y.getRGB();
}
if (((j - 1) % width != 0) && (j - 1 + width < buffer.length))
{
Color x = new Color(buffer[(j - 1 + width)], true);
Color y = new Color(Math.max(0, Math.min(x.getRed() + col.getAlpha() / 255 * quantErrorR * 3 / 16, 255)), Math.max(0, Math.min(x.getGreen() + col.getAlpha() / 255 * quantErrorG * 3 / 16, 255)), Math.max(0, Math.min(x.getBlue() + col.getAlpha() / 255 * quantErrorB * 3 / 16, 255)), x.getAlpha());
buffer[(j - 1 + width)] = y.getRGB();
}
if (j + width < buffer.length)
{
Color x = new Color(buffer[(j + width)], true);
Color y = new Color(Math.max(0, Math.min(x.getRed() + col.getAlpha() / 255 * quantErrorR * 5 / 16, 255)), Math.max(0, Math.min(x.getGreen() + col.getAlpha() / 255 * quantErrorG * 5 / 16, 255)), Math.max(0, Math.min(x.getBlue() + col.getAlpha() / 255 * quantErrorB * 5 / 16, 255)), x.getAlpha());
buffer[(j + width)] = y.getRGB();
}
if (((j + 1) % width != 0) && (j + 1 + width < buffer.length))
{
Color x = new Color(buffer[(j + 1 + width)], true);
Color y = new Color(Math.max(0, Math.min(x.getRed() + col.getAlpha() / 255 * quantErrorR * 1 / 16, 255)), Math.max(0, Math.min(x.getGreen() + col.getAlpha() / 255 * quantErrorG * 1 / 16, 255)), Math.max(0, Math.min(x.getBlue() + col.getAlpha() / 255 * quantErrorB * 1 / 16, 255)), x.getAlpha());
buffer[(j + 1 + width)] = y.getRGB();
}
if (current.getAlpha() >= 128)
{
if (k2 < colors.length / 2) {
simple[j] = Color.WHITE.getRGB();
} else {
simple[j] = Color.BLACK.getRGB();
}
}
else {
simple[j] = new Color(255, 255, 255, 0).getRGB();
}
}
return c.createImage(new MemoryImageSource(width, height, simple, 0, width));
}
public static Image resize(Image i, int[] buffer, Component c, int newDim)
{
int h = i.getHeight(c);
int w = i.getWidth(c);
if (w < h) {
return resize(i, buffer, c, newDim, (int)(newDim * 1.0D * w / h));
}
return resize(i, buffer, c, (int)(newDim * 1.0D * h / w), newDim);
}
public static int getResizedHeight(Image i, Component c, int newDim)
{
int h = i.getHeight(c);
int w = i.getWidth(c);
if (w < h) {
return newDim;
}
return (int)(newDim * 1.0D * h / w);
}
public static int getResizedWidth(Image i, Component c, int newDim)
{
int h = i.getHeight(c);
int w = i.getWidth(c);
if (w < h) {
return (int)(newDim * 1.0D * w / h);
}
return newDim;
}
public static int[] resizebuff(Image i, int[] buffer, Component c, int newDim)
{
int h = i.getHeight(c);
int w = i.getWidth(c);
if (w < h) {
return resizebuff(i, buffer, c, newDim, (int)(newDim * 1.0D * w / h));
}
return resizebuff(i, buffer, c, (int)(newDim * 1.0D * h / w), newDim);
}
public static Image resize2(Image i, int[] buffer, Component c, int newDim)
{
int h = i.getHeight(c);
int w = i.getWidth(c);
if (w < h) {
return resize2(i, buffer, c, newDim, (int)(newDim * 1.0D * w / h));
}
return resize2(i, buffer, c, (int)(newDim * 1.0D * h / w), newDim);
}
public static int[] resize2buff(Image i, int[] buffer, Component c, int newDim)
{
int h = i.getHeight(c);
int w = i.getWidth(c);
if (w < h) {
return resize2buff(i, buffer, c, newDim, (int)(newDim * 1.0D * w / h));
}
return resize2buff(i, buffer, c, (int)(newDim * 1.0D * h / w), newDim);
}
public static Image resize(Image i, int[] buffer, Component c, int newHeight, int newWidth)
{
if (newHeight < 2) {
newHeight = 2;
}
if (newWidth < 2) {
newWidth = 2;
}
int height = i.getHeight(c);
int width = i.getWidth(c);
if ((height == newHeight) && (width == newWidth)) {
return i;
}
int[] resized = new int[newHeight * newWidth];
double hRatio = newHeight / height;
double wRatio = newWidth / width;
for (int y = 0; y < newHeight; y++) {
for (int x = 0; x < newWidth; x++)
{
int oldX = (int)(x / wRatio);
int oldY = (int)(y / hRatio);
resized[(y * newWidth + x)] = buffer[(oldY * width + oldX)];
}
}
return c.createImage(new MemoryImageSource(newWidth, newHeight, resized, 0, newWidth));
}
public static int[] resizebuff(Image i, int[] buffer, Component c, int newHeight, int newWidth)
{
if (newHeight < 2) {
newHeight = 2;
}
if (newWidth < 2) {
newWidth = 2;
}
int height = i.getHeight(c);
int width = i.getWidth(c);
if ((height == newHeight) && (width == newWidth)) {
return buffer;
}
int[] resized = new int[newHeight * newWidth];
double hRatio = newHeight / height;
double wRatio = newWidth / width;
for (int y = 0; y < newHeight; y++) {
for (int x = 0; x < newWidth; x++)
{
int oldX = (int)(x / wRatio);
int oldY = (int)(y / hRatio);
resized[(y * newWidth + x)] = buffer[(oldY * width + oldX)];
}
}
return resized;
}
public static Image resize2(Image i, int[] buffer, Component c, int newHeight, int newWidth)
{
if (newHeight < 2) {
newHeight = 2;
}
if (newWidth < 2) {
newWidth = 2;
}
int height = i.getHeight(c);
int width = i.getWidth(c);
if ((height == newHeight) && (width == newWidth)) {
return i;
}
int[] resized = new int[newHeight * newWidth];
double hRatio = newHeight / height;
double wRatio = newWidth / width;
if ((hRatio > 1.0D) || (wRatio > 1.0D)) {
return resize(i, buffer, c, newHeight, newWidth);
}
for (int y = 0; y < newHeight; y++) {
for (int x = 0; x < newWidth; x++)
{
int k = 0;
double oldC = 0.0D;
double oldRed = 0.0D;
double oldGreen = 0.0D;
double oldBlue = 0.0D;
double oldAlpha = 0.0D;
for (int q = (int)(x / wRatio); q < (int)((x + 1) / wRatio); q++) {
for (int j = (int)(y / hRatio); j < (int)((y + 1) / hRatio); j++)
{
Color oldColor = new Color(buffer[(j * width + q)], true);
oldRed = (oldRed * k + oldColor.getRed()) / (k + 1);
oldGreen = (oldGreen * k + oldColor.getGreen()) / (k + 1);
oldBlue = (oldBlue * k + oldColor.getBlue()) / (k + 1);
oldAlpha = (oldAlpha * k + oldColor.getAlpha()) / (k + 1);
k++;
}
}
resized[(y * newWidth + x)] = new Color((int)oldRed, (int)oldGreen, (int)oldBlue, (int)oldAlpha).getRGB();
}
}
return c.createImage(new MemoryImageSource(newWidth, newHeight, resized, 0, newWidth));
}
public static int[] resize2buff(Image i, int[] buffer, Component c, int newHeight, int newWidth)
{
if (newHeight < 2) {
newHeight = 2;
}
if (newWidth < 2) {
newWidth = 2;
}
int height = i.getHeight(c);
int width = i.getWidth(c);
if ((height == newHeight) && (width == newWidth)) {
return buffer;
}
int[] resized = new int[newHeight * newWidth];
double hRatio = newHeight / height;
double wRatio = newWidth / width;
if ((hRatio > 1.0D) || (wRatio > 1.0D)) {
return resizebuff(i, buffer, c, newHeight, newWidth);
}
for (int y = 0; y < newHeight; y++) {
for (int x = 0; x < newWidth; x++)
{
int k = 0;
double oldC = 0.0D;
double oldRed = 0.0D;
double oldGreen = 0.0D;
double oldBlue = 0.0D;
double oldAlpha = 0.0D;
for (int q = (int)(x / wRatio); q < (int)((x + 1) / wRatio); q++) {
for (int j = (int)(y / hRatio); j < (int)((y + 1) / hRatio); j++)
{
Color oldColor = new Color(buffer[(j * width + q)], true);
oldRed = (oldRed * k + oldColor.getRed()) / (k + 1);
oldGreen = (oldGreen * k + oldColor.getGreen()) / (k + 1);
oldBlue = (oldBlue * k + oldColor.getBlue()) / (k + 1);
oldAlpha = (oldAlpha * k + oldColor.getAlpha()) / (k + 1);
k++;
}
}
resized[(y * newWidth + x)] = new Color((int)oldRed, (int)oldGreen, (int)oldBlue, (int)oldAlpha).getRGB();
}
}
return resized;
}
public static int[] countColors(int[] buffer, Component c, Color[] colors)
{
int[] count = new int[colors.length];
for (int k = 0; k < count.length; k++) {
count[k] = 0;
}
Color col = Color.BLACK;
for (int j = 0; j < buffer.length; j++)
{
col = new Color(buffer[j]);
for (int k = 0; k < colors.length; k++) {
if ((colors[k] != null) && (colors[k].getRGB() == col.getRGB())) {
count[k] += 1;
}
}
}
return count;
}
(Had to cut it off b/c of character limit)
EDIT: Turns out the first error doesn't matter. The program tries to run textures from a separate file. If it isn't found, it skips it.
Any help is appreciated.
Addressing your second issue with the stack trace:
This line is your issue:
resized[(y * newWidth + x)] = buffer[(oldY * width + oldX)];
Specifically this part resized[(y * newWidth + x)] because [y * newWidth + x] can be far bigger than what resized allows.
Let's assume the image is 100x50 (WxH), this means that int[] resized = new int[newHeight * newWidth]; will create a new array that is 5000 long.
However the for loops will create something much higher:
for (int y = 0; y < newHeight; y++) in this instance y will go as high as newHeight or 100
vfor (int x = 0; x < newWidth; x++)in this instanceywill go as high asnewWidth` or 50
So:
resized[(y * newWidth + x)] = something; will be an issue because 100 * 100 + 50 can be as large as 10050, that is far bigger than 5000.
The solution is to make a larger resized array, or to rethink your for loops.
Related
How to test this my functions?
a want to test this function. Can you please write a test for one of those methods? I already read about JUnit testing but i really have no clue how to test this. public class SomeClass { #Override public void render(Screen screen) { int xTile = playerLook[0]; int yTile = playerLook[1]; int walkingSpeed = 4; int flipTop = (numSteps >> walkingSpeed) & 1; int flipBottom = (numSteps >> walkingSpeed) & 1; if (movingDir == 1) { xTile += 2; } else if (movingDir > 1) { xTile += 4 + ((numSteps >> walkingSpeed) & 1) * 2; flipTop = (movingDir - 1) % 2; } int modifier = 8 * scale; int xOffset = x - modifier / 2; int yOffset = y - modifier / 2 - 4; if (isSwimming) { int waterColor = 0; yOffset += 4; if (tickCount % 60 < 15) { waterColor = Colors.get(-1, -1, 225, -1); } else if ((15 <= tickCount % 60) && (tickCount % 60 < 30)) { yOffset -= 1; waterColor = Colors.get(-1, 225, 115, -1); } else if ((30 <= tickCount % 60) && (tickCount % 60 < 45)) { waterColor = Colors.get(-1, 115, -1, 225); } else { yOffset -= 1; waterColor = Colors.get(-1, 225, 115, -1); } screen.render(xOffset, yOffset + 3, 0 + 27 * MAP_TILE_SIZE, waterColor, 0x00, 1); screen.render(xOffset + 8, yOffset + 3, 0 + 27 * MAP_TILE_SIZE, waterColor, 0x01, 1); } screen.render(xOffset + (modifier * flipTop), yOffset, xTile + yTile * MAP_TILE_SIZE, color, flipTop, scale); screen.render(xOffset + modifier - (modifier * flipTop), yOffset, (xTile + 1) + yTile * MAP_TILE_SIZE, color, flipTop, scale); if (!isSwimming) { screen.render(xOffset + (modifier * flipBottom), yOffset + modifier, xTile + (yTile + 1) * MAP_TILE_SIZE, color, flipBottom, scale); screen.render(xOffset + modifier - (modifier * flipBottom), yOffset + modifier, (xTile + 1) + (yTile + 1) * MAP_TILE_SIZE, color, flipBottom, scale); } } #Override public boolean hasCollided(int xa, int ya) { int xMin = 0; int xMax = 7; int yMin = 3; int yMax = 7; for (int x = xMin; x < xMax; x++) { if (isSolidTile(xa, ya, x, yMin)) { return true; } } for (int x = xMin; x < xMax; x++) { if (isSolidTile(xa, ya, x, yMax)) { return true; } } for (int y = yMin; y < yMax; y++) { if (isSolidTile(xa, ya, xMin, y)) { return true; } } for (int y = yMin; y < yMax; y++) { if (isSolidTile(xa, ya, xMax, y)) { return true; } } return false; } } would really appreciate some help. Thank you guys
Java: implementation of Gaussian Blur
I need to implement Gaussian Blur in Java for 3x3, 5x5 and 7x7 matrix. Can you correct me if I'm wrong: I've a matrix(M) 3x3 (middle value is M(0, 0)): 1 2 1 2 4 2 1 2 1 I take one pixel(P) from image and for each nearest pixel: s = M(-1, -1) * P(-1, -1) + M(-1, 0) * P(-1, 0) + ... + M(1, 1) * P(1, 1) An then division it total value of matrix: P'(i, j) = s / M(-1, -1) + M(-1, 0) + ... + M(1, 1) That's all that my program do. I leave extreme pixels not changed. My program: for(int i = 1; i < height - 1; i++){ for(int j = 1; j < width - 1; j++){ int sum = 0, l = 0; for(int m = -1; m <= 1; m++){ for(int n = -1; n <= 1; n++){ try{ System.out.print(l + " "); sum += mask3[l++] * Byte.toUnsignedInt((byte) source[(i + m) * height + j + n]); } catch(ArrayIndexOutOfBoundsException e){ int ii = (i + m) * height, jj = j + n; System.out.println("Pixels[" + ii + "][" + jj + "] " + i + ", " + j); System.exit(0); } } System.out.println(); } System.out.println(); output[i * width + j] = sum / maskSum[0]; } } I get source from a BufferedImage like this: int[] source = image.getRGB(0, 0, width, height, null, 0, width); So for this image: Result is this: Can you describe me, what is wrong with my program?
First of all, your formula for calculating the index in the source array is wrong. The image data is stored in the array one pixel row after the other. Therefore the index given x and y is calculated like this: index = x + y * width Furthermore the color channels are stored in different bits of the int cannot simply do the calculations with the whole int, since this allows channels to influence other channels. The following solution should work (even though it just leaves the pixels at the bounds transparent): public static BufferedImage blur(BufferedImage image, int[] filter, int filterWidth) { if (filter.length % filterWidth != 0) { throw new IllegalArgumentException("filter contains a incomplete row"); } final int width = image.getWidth(); final int height = image.getHeight(); final int sum = IntStream.of(filter).sum(); int[] input = image.getRGB(0, 0, width, height, null, 0, width); int[] output = new int[input.length]; final int pixelIndexOffset = width - filterWidth; final int centerOffsetX = filterWidth / 2; final int centerOffsetY = filter.length / filterWidth / 2; // apply filter for (int h = height - filter.length / filterWidth + 1, w = width - filterWidth + 1, y = 0; y < h; y++) { for (int x = 0; x < w; x++) { int r = 0; int g = 0; int b = 0; for (int filterIndex = 0, pixelIndex = y * width + x; filterIndex < filter.length; pixelIndex += pixelIndexOffset) { for (int fx = 0; fx < filterWidth; fx++, pixelIndex++, filterIndex++) { int col = input[pixelIndex]; int factor = filter[filterIndex]; // sum up color channels seperately r += ((col >>> 16) & 0xFF) * factor; g += ((col >>> 8) & 0xFF) * factor; b += (col & 0xFF) * factor; } } r /= sum; g /= sum; b /= sum; // combine channels with full opacity output[x + centerOffsetX + (y + centerOffsetY) * width] = (r << 16) | (g << 8) | b | 0xFF000000; } } BufferedImage result = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB); result.setRGB(0, 0, width, height, output, 0, width); return result; } int[] filter = {1, 2, 1, 2, 4, 2, 1, 2, 1}; int filterWidth = 3; BufferedImage blurred = blur(img, filter, filterWidth);
Java, Colours of a buffered image are completely different to the original image
I am trying to add some texture to my game. I am running into some problems getting the image to display properly. This is what the texture should look like, just a boring black square: And this is what I get. A little bit of black with blue lines. This is the code I used to import the image. The BufferedImage is set to Type_INT_RGB: package com.mime.minefront.graphics; import java.awt.image.BufferedImage; import javax.imageio.ImageIO; public class Texture { public static Render floor = loadBitmap("/textures/floorb.png"); public static Render loadBitmap(String fileName) { try { BufferedImage image = ImageIO.read(Texture.class.getResource(fileName)); int width = image.getWidth(); int height = image.getHeight(); Render result = new Render(width, height); image.getRGB(0, 0, width, height, result.pixels, 0, width); return result; } catch (Exception e) { System.out.println("CRASH!"); throw new RuntimeException(e); } } } Any help or advice would be great. I have tried to search for the answer but with no luck. This is my Render class. package com.mime.minefront.graphics; public class Render { public final int width; public final int height; public final int[] pixels; public Render(int width, int height) { this.width = width; this.height = height; pixels = new int[width * height]; } public void draw(Render render, int xOffset, int yOffset) { for (int y = 0; y < render.height; y++) { int yPix = y + yOffset; if (yPix < 0 || yPix >= height) { continue; } for (int x = 0; x < render.width; x++) { int xPix = x + xOffset; if (xPix < 0 || xPix >= width) { continue; } int aplha = render.pixels[x + y * render.width]; if (aplha > 0) { pixels[xPix + yPix * width] = aplha; } } } } } and this is my Render3D class package com.mime.minefront.graphics; import com.mime.minefront.Game; import com.mimi.minefront.input.Controller; import com.mimi.minefront.input.InputHandler; import java.awt.Robot; import java.util.Random; public class Render3D extends Render { public double[] zBuffer; private double renderDistance = 5000; private double forward, right, up, cosine, sine; public Render3D(int width, int height) { super(width, height); zBuffer = new double[width * height]; } public void floor(Game game) { double floorPosition = 8; double cellingPosition = 8; forward = game.controls.z; right = game.controls.x; up = game.controls.y; double walking = Math.sin(game.time / 6.0) * 0.5; if (Controller.crouchWalk) { walking = Math.sin(game.time / 6.0) * 0.25; } if (Controller.runWalk) { walking = Math.sin(game.time / 6.0) * 0.8; } double rotation = 0;//Math.sin(game.time / 20) * 0.5; //game.controls.rotation; cosine = Math.cos(rotation); sine = Math.sin(rotation); for (int y = 0; y < height; y++) { double celling = (y - height / 2.0) / height; double z = (floorPosition + up) / celling; if (Controller.walk) { z = (floorPosition + up + walking) / celling; } if (celling < 0) { z = (cellingPosition - up) / -celling; if (Controller.walk) { z = (cellingPosition - up - walking) / -celling; } } for (int x = 0; x < width; x++) { double depth = (x - width / 2.0) / height; depth *= z; double xx = depth * cosine + z * sine; double yy = z * cosine - depth * sine; int xPix = (int) (xx + right); int yPix = (int) (yy + forward); zBuffer[x + y * width] = z; pixels[x + y * width] = //((xPix & 15) * 16 | ((yPix % 15) * 16) << 8); Texture.floor.pixels[xPix & 7] + (yPix & 7) * 8; if (z > 500) { pixels[x + y * width] = 0; } } } } public void renderWall(double xLeft, double xRight, double zDistance, double yHeight) { double xcLeft = ((xLeft) - right) * 2; double zcLeft = ((zDistance) - forward) * 2; double rotLeftSideX = xcLeft * cosine - zcLeft * sine; double yCornerTL = ((-yHeight) - up) * 2; double yCornerBL = ((+0.5 - yHeight) - up) * 2; double rotLeftSideZ = zcLeft * cosine + xcLeft * sine; double xcRight = ((xRight) - right) * 2; double zcRight = ((zDistance) - forward) * 2; double rotRightSideX = xcRight * cosine - zcLeft * sine; double yCornerTR = ((-yHeight) - up) * 2; double yCornerBR = ((+0.5 - yHeight) - up) * 2; double rotRightSideZ = zcRight * cosine + xcRight * sine; double xPixelLeft = (rotLeftSideX / rotLeftSideZ * height + width / 2); double xPixelRight = (rotRightSideX / rotRightSideZ * height + width / 2); if (xPixelLeft >= xPixelRight) { return; } int xPixelLeftInt = (int) (xPixelLeft); int xPixelRightInt = (int) (xPixelRight); if (xPixelLeftInt < 0) { xPixelLeftInt = 0; } if (xPixelRightInt > width) { xPixelRightInt = width; } double yPixelLeftTop = (yCornerTL / rotLeftSideZ * height + height / 2); double yPixelLeftBottom = (yCornerBL / rotLeftSideZ * height + height / 2); double yPixelRightTop = (yCornerTR / rotRightSideZ * height + height / 2); double yPixelRightBottom = (yCornerBR / rotRightSideZ * height + height / 2); double tex1 = 1 / rotLeftSideZ; double tex2 = 1 / rotRightSideZ; double tex3 = 0 / rotLeftSideZ; double tex4 = 8 / rotRightSideZ - tex3; for (int x = xPixelLeftInt; x < xPixelRightInt; x++) { double pixelRotation = (x - xPixelLeft) / (xPixelRight - xPixelLeft); double xTexture= (int) ((tex3+tex4*pixelRotation)/tex1+(tex2-tex1)*pixelRotation); double yPixelTop = yPixelLeftTop + (yPixelRightTop - yPixelLeftTop) * pixelRotation; double yPixelBottom = yPixelLeftBottom + (yPixelRightBottom - yPixelLeftBottom) * pixelRotation; int yPixelTopInt = (int) (yPixelTop); int yPixelBottomInt = (int) (yPixelBottom); if (yPixelTopInt < 0) { yPixelTopInt = 0; } if (yPixelBottomInt > height) { yPixelBottomInt = height; } for (int y = yPixelTopInt; y < yPixelBottomInt; y++) { pixels[x + y * width] = (int) xTexture*100; zBuffer[x + y * width] = 0; } } } public void renderDistanceLimiter() { for (int i = 0; i < width * height; i++) { int colour = pixels[i]; int brightness = (int) (renderDistance / (zBuffer[i])); if (brightness < 0) { brightness = 0; } if (brightness > 255) { brightness = 255; } int r = (colour >> 16) & 0xff; int g = (colour >> 8) & 0xff; int b = (colour) & 0xff; r = r * brightness / 255; g = g * brightness / 255; b = b * brightness / 255; pixels[i] = r << 16 | g << 8 | b; } } }
From getRGB() : Returns an array of integer pixels in the default RGB color model (TYPE_INT_ARGB) and default sRGB color space, from a portion of the image data. Color conversion takes place if the default model does not match the image ColorModel See if using TYPE_INT_ARGB instead of TYPE_INT_RGB works.
Drawing on top of ImageView
I found some code that draws the histogram but I am not sure how to make it show the histogram of _tempBitmaps[0] once the user clicks on a ShowRGB Histogram Button I want the graphs to be displayed on top of ImageView once the user clicks the button display_RGB and when the user clicks the button again the graphs disappear. I have also attached a mockup of the layout and the graphs that I wish to achieve. Mockup: Below is the sample code I found for histogram and it works but currently some of the variables arent initialised and thats what I need help with : class DrawOnTop extends View { Bitmap mBitmap; Paint mPaintBlack; Paint mPaintYellow; Paint mPaintRed; Paint mPaintGreen; Paint mPaintBlue; byte[] mYUVData; int[] mRGBData; int mImageWidth, mImageHeight; int[] mRedHistogram; int[] mGreenHistogram; int[] mBlueHistogram; double[] mBinSquared; public DrawOnTop(Context context) { super(context); mPaintBlack = new Paint(); mPaintBlack.setStyle(Paint.Style.FILL); mPaintBlack.setColor(Color.BLACK); mPaintBlack.setTextSize(25); mPaintYellow = new Paint(); mPaintYellow.setStyle(Paint.Style.FILL); mPaintYellow.setColor(Color.YELLOW); mPaintYellow.setTextSize(25); mPaintRed = new Paint(); mPaintRed.setStyle(Paint.Style.FILL); mPaintRed.setColor(Color.RED); mPaintRed.setTextSize(25); mPaintGreen = new Paint(); mPaintGreen.setStyle(Paint.Style.FILL); mPaintGreen.setColor(Color.GREEN); mPaintGreen.setTextSize(25); mPaintBlue = new Paint(); mPaintBlue.setStyle(Paint.Style.FILL); mPaintBlue.setColor(Color.BLUE); mPaintBlue.setTextSize(25); mBitmap = null; mYUVData = null; mRGBData = null; mRedHistogram = new int[256]; mGreenHistogram = new int[256]; mBlueHistogram = new int[256]; mBinSquared = new double[256]; for (int bin = 0; bin < 256; bin++) { mBinSquared[bin] = ((double)bin) * bin; } // bin } #Override protected void onDraw(Canvas canvas) { if (mBitmap != null) { int canvasWidth = canvas.getWidth(); int canvasHeight = canvas.getHeight(); int newImageWidth = canvasWidth; int newImageHeight = canvasHeight; int marginWidth = (canvasWidth - newImageWidth)/2; // Convert from YUV to RGB decodeYUV420SP(mRGBData, mYUVData, mImageWidth, mImageHeight); // Draw bitmap mBitmap.setPixels(mRGBData, 0, mImageWidth, 0, 0, mImageWidth, mImageHeight); Rect src = new Rect(0, 0, mImageWidth, mImageHeight); Rect dst = new Rect(marginWidth, 0, canvasWidth-marginWidth, canvasHeight); canvas.drawBitmap(mBitmap, src, dst, mPaintBlack); // Draw black borders canvas.drawRect(0, 0, marginWidth, canvasHeight, mPaintBlack); canvas.drawRect(canvasWidth - marginWidth, 0, canvasWidth, canvasHeight, mPaintBlack); // Calculate histogram calculateIntensityHistogram(mRGBData, mRedHistogram, mImageWidth, mImageHeight, 0); calculateIntensityHistogram(mRGBData, mGreenHistogram, mImageWidth, mImageHeight, 1); calculateIntensityHistogram(mRGBData, mBlueHistogram, mImageWidth, mImageHeight, 2); // Calculate mean double imageRedMean = 0, imageGreenMean = 0, imageBlueMean = 0; double redHistogramSum = 0, greenHistogramSum = 0, blueHistogramSum = 0; for (int bin = 0; bin < 256; bin++) { imageRedMean += mRedHistogram[bin] * bin; redHistogramSum += mRedHistogram[bin]; imageGreenMean += mGreenHistogram[bin] * bin; greenHistogramSum += mGreenHistogram[bin]; imageBlueMean += mBlueHistogram[bin] * bin; blueHistogramSum += mBlueHistogram[bin]; } // bin imageRedMean /= redHistogramSum; imageGreenMean /= greenHistogramSum; imageBlueMean /= blueHistogramSum; // Calculate second moment double imageRed2ndMoment = 0, imageGreen2ndMoment = 0, imageBlue2ndMoment = 0; for (int bin = 0; bin < 256; bin++) { imageRed2ndMoment += mRedHistogram[bin] * mBinSquared[bin]; imageGreen2ndMoment += mGreenHistogram[bin] * mBinSquared[bin]; imageBlue2ndMoment += mBlueHistogram[bin] * mBinSquared[bin]; } // bin imageRed2ndMoment /= redHistogramSum; imageGreen2ndMoment /= greenHistogramSum; imageBlue2ndMoment /= blueHistogramSum; double imageRedStdDev = Math.sqrt( imageRed2ndMoment - imageRedMean*imageRedMean ); double imageGreenStdDev = Math.sqrt( imageGreen2ndMoment - imageGreenMean*imageGreenMean ); double imageBlueStdDev = Math.sqrt( imageBlue2ndMoment - imageBlueMean*imageBlueMean ); // Draw mean String imageMeanStr = "Mean (R,G,B): " + String.format("%.4g", imageRedMean) + ", " + String.format("%.4g", imageGreenMean) + ", " + String.format("%.4g", imageBlueMean); canvas.drawText(imageMeanStr, marginWidth+10-1, 30-1, mPaintBlack); canvas.drawText(imageMeanStr, marginWidth+10+1, 30-1, mPaintBlack); canvas.drawText(imageMeanStr, marginWidth+10+1, 30+1, mPaintBlack); canvas.drawText(imageMeanStr, marginWidth+10-1, 30+1, mPaintBlack); canvas.drawText(imageMeanStr, marginWidth+10, 30, mPaintYellow); // Draw standard deviation String imageStdDevStr = "Std Dev (R,G,B): " + String.format("%.4g", imageRedStdDev) + ", " + String.format("%.4g", imageGreenStdDev) + ", " + String.format("%.4g", imageBlueStdDev); canvas.drawText(imageStdDevStr, marginWidth+10-1, 60-1, mPaintBlack); canvas.drawText(imageStdDevStr, marginWidth+10+1, 60-1, mPaintBlack); canvas.drawText(imageStdDevStr, marginWidth+10+1, 60+1, mPaintBlack); canvas.drawText(imageStdDevStr, marginWidth+10-1, 60+1, mPaintBlack); canvas.drawText(imageStdDevStr, marginWidth+10, 60, mPaintYellow); // Draw red intensity histogram float barMaxHeight = 3000; float barWidth = ((float)newImageWidth) / 256; float barMarginHeight = 2; RectF barRect = new RectF(); barRect.bottom = canvasHeight - 200; barRect.left = marginWidth; barRect.right = barRect.left + barWidth; for (int bin = 0; bin < 256; bin++) { float prob = (float)mRedHistogram[bin] / (float)redHistogramSum; barRect.top = barRect.bottom - Math.min(80,prob*barMaxHeight) - barMarginHeight; canvas.drawRect(barRect, mPaintBlack); barRect.top += barMarginHeight; canvas.drawRect(barRect, mPaintRed); barRect.left += barWidth; barRect.right += barWidth; } // bin // Draw green intensity histogram barRect.bottom = canvasHeight - 100; barRect.left = marginWidth; barRect.right = barRect.left + barWidth; for (int bin = 0; bin < 256; bin++) { barRect.top = barRect.bottom - Math.min(80, ((float)mGreenHistogram[bin])/((float)greenHistogramSum) * barMaxHeight) - barMarginHeight; canvas.drawRect(barRect, mPaintBlack); barRect.top += barMarginHeight; canvas.drawRect(barRect, mPaintGreen); barRect.left += barWidth; barRect.right += barWidth; } // bin // Draw blue intensity histogram barRect.bottom = canvasHeight; barRect.left = marginWidth; barRect.right = barRect.left + barWidth; for (int bin = 0; bin < 256; bin++) { barRect.top = barRect.bottom - Math.min(80, ((float)mBlueHistogram[bin])/((float)blueHistogramSum) * barMaxHeight) - barMarginHeight; canvas.drawRect(barRect, mPaintBlack); barRect.top += barMarginHeight; canvas.drawRect(barRect, mPaintBlue); barRect.left += barWidth; barRect.right += barWidth; } // bin } // end if statement super.onDraw(canvas); } // end onDraw method static public void decodeYUV420SP(int[] rgb, byte[] yuv420sp, int width, int height) { final int frameSize = width * height; for (int j = 0, yp = 0; j < height; j++) { int uvp = frameSize + (j >> 1) * width, u = 0, v = 0; for (int i = 0; i < width; i++, yp++) { int y = (0xff & ((int) yuv420sp[yp])) - 16; if (y < 0) y = 0; if ((i & 1) == 0) { v = (0xff & yuv420sp[uvp++]) - 128; u = (0xff & yuv420sp[uvp++]) - 128; } int y1192 = 1192 * y; int r = (y1192 + 1634 * v); int g = (y1192 - 833 * v - 400 * u); int b = (y1192 + 2066 * u); if (r < 0) r = 0; else if (r > 262143) r = 262143; if (g < 0) g = 0; else if (g > 262143) g = 262143; if (b < 0) b = 0; else if (b > 262143) b = 262143; rgb[yp] = 0xff000000 | ((r << 6) & 0xff0000) | ((g >> 2) & 0xff00) | ((b >> 10) & 0xff); } } } static public void decodeYUV420SPGrayscale(int[] rgb, byte[] yuv420sp, int width, int height) { final int frameSize = width * height; for (int pix = 0; pix < frameSize; pix++) { int pixVal = (0xff & ((int) yuv420sp[pix])) - 16; if (pixVal < 0) pixVal = 0; if (pixVal > 255) pixVal = 255; rgb[pix] = 0xff000000 | (pixVal << 16) | (pixVal << 8) | pixVal; } // pix } static public void calculateIntensityHistogram(int[] rgb, int[] histogram, int width, int height, int component) { for (int bin = 0; bin < 256; bin++) { histogram[bin] = 0; } // bin if (component == 0) // red { for (int pix = 0; pix < width*height; pix += 3) { int pixVal = (rgb[pix] >> 16) & 0xff; histogram[ pixVal ]++; } // pix } else if (component == 1) // green { for (int pix = 0; pix < width*height; pix += 3) { int pixVal = (rgb[pix] >> 8) & 0xff; histogram[ pixVal ]++; } // pix } else // blue { for (int pix = 0; pix < width*height; pix += 3) { int pixVal = rgb[pix] & 0xff; histogram[ pixVal ]++; } // pix } } } This is the class where I wish to create the button which will create the histogram: public class testrgb extends Activity { /************************ * PROPERTIES **********************/ /* Tag for Log */ public static final String TAG = "PiccaFinal.EditPicturesActivity"; /* Images Path */ private String[] _imagesPath; /* Original Images */ private Bitmap[] _originalBitmaps = new Bitmap[2]; /* Final Filtered Images */ private Bitmap[] _filteredBitmaps = new Bitmap[2]; /* Image View */ private ImageView _filterImageView; private Preview mPreview; private DrawOnTop mDrawOnTop; int[] pixels; /************************ * ANDROID METHODS **********************/ #Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); getWindow().setFormat(PixelFormat.TRANSLUCENT); requestWindowFeature(Window.FEATURE_NO_TITLE); getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); setContentView(R.layout.activity_edit_pictures); Intent intent = getIntent(); _imagesPath = intent.getStringArrayExtra(MainActivity.IMAGES_PATH); for (int i = MainActivity.LEFT_IMAGE; i <= MainActivity.RIGHT_IMAGE; i++) { _originalBitmaps[i] = BitmapFactory.decodeFile(_imagesPath[i]); } _filterImageView = (ImageView) findViewById(R.id.filter_image_view); _filterImageView .setImageBitmap(_originalBitmaps[MainActivity.LEFT_IMAGE]); // -------------------------------------------------------------------------------- // display_RGB Button display_RGBButton = (Button) findViewById(R.id.display_RGB); display_RGBButton.setOnClickListener(new View.OnClickListener() { #Override public void onClick(View v) { //what should I do here }); } }
Rotate Bitmap pixels
I'm trying to rotate a Bitmap where the pixels are stored in an Array int pixels[]. I got the following method: public void rotate(double angle) { double radians = Math.toRadians(angle); double cos, sin; cos = Math.cos(radians); sin = Math.sin(radians); int[] pixels2 = pixels; for (int x = 0; x < width; x++) for (int y = 0; y < height; y++) { int centerx = this.width / 2, centery = this.height / 2; int m = x - centerx; int n = y - centery; int j = (int) (m * cos + n * sin); int k = (int) (n * cos - m * sin); j += centerx; k += centery; if (!((j < 0) || (j > this.width - 1) || (k < 0) || (k > this.height - 1))) try { pixels2[(x * this.width + y)] = pixels[(k * this.width + j)]; } catch (Exception e) { e.printStackTrace(); } } pixels = pixels2; } But it just gives me crazy results. Does anyone know where the error is?
The line int[] pixels2 = pixels; is supposed to copy the array, but you are just copying the reference to it. Use pixels.clone(). In fact, you just need a new, empty array, so new int[pixels.lenght] is enough. In the end you need System.arraycopy to copy the new content into the old array. There are other problems in your code -- you are mixing up rows and columns. Some expressions are written as though the image is stored row by row, others as if column by column. If row-by-row (my assumption), then this doesn't make sense: x*width + y. It should read y*width + x -- you are skipping y rows down and then moving x columns to the right. All in all, I have this code that works OK: import static java.lang.System.arraycopy; public class Test { private final int width = 5, height = 5; private int[] pixels = {0,0,1,0,0, 0,0,1,0,0, 0,0,1,0,0, 0,0,1,0,0, 0,0,1,0,0}; public Test rotate(double angle) { final double radians = Math.toRadians(angle), cos = Math.cos(radians), sin = Math.sin(radians); final int[] pixels2 = new int[pixels.length]; for (int x = 0; x < width; x++) for (int y = 0; y < height; y++) { final int centerx = this.width / 2, centery = this.height / 2, m = x - centerx, n = y - centery, j = ((int) (m * cos + n * sin)) + centerx, k = ((int) (n * cos - m * sin)) + centery; if (j >= 0 && j < width && k >= 0 && k < this.height) pixels2[(y * width + x)] = pixels[(k * width + j)]; } arraycopy(pixels2, 0, pixels, 0, pixels.length); return this; } public Test print() { for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) System.out.print(pixels[width*y + x]); System.out.println(); } System.out.println(); return this; } public static void main(String[] args) { new Test().print().rotate(-45).print(); } }
public void render(float nx, float ny, float nz, float size, float rotate) { int wid = (int) ((width - nz) * size); int hgt = (int) ((height - nz) * size); if (wid < 0 || hgt < 0) { wid = 0; hgt = 0; } for (int x = 0; x < wid; x++) { for (int y = 0; y < hgt; y++) { double simple = Math.PI; int xp = (int) (nx + Math.cos(rotate) * ((x / simple) - (wid / simple) / 2) + Math .cos(rotate + Math.PI / 2) * ((y / simple) - (hgt / simple) / 2)); int yp = (int) (ny + Math.sin(rotate) * ((x / simple) - (wid / simple) / 2) + Math.sin(rotate + Math.PI / 2) * ((y / simple) - (hgt / simple) / 2)); if (xp + width < 0 || yp + height < 0 || xp >= Main.width || yp >= Main.height) { break; } if (xp < 0 || yp < 0 || pixels[(width / wid) * x + ((height / hgt) * y) * width] == 0xFFFF00DC) { continue; } Main.pixels[xp + yp * Main.width] = pixels[(width / wid) * x + ((height / hgt) * y) * width]; } } } This is only a new to rotating for me, but the process of this is that of a normal rotation. It still needs much fixing -- it's inefficient and slow. But in a small program, this code works. I'm posting this so you can take it, and make it better. :)