Skip to content

Instantly share code, notes, and snippets.

@mrkn
Created July 13, 2009 04:52
Show Gist options
  • Save mrkn/145937 to your computer and use it in GitHub Desktop.
Save mrkn/145937 to your computer and use it in GitHub Desktop.
// PixelData.java
import javax.microedition.lcdui.*;
public class PixelData {
private int[] pixels;
private int width;
private int height;
private PixelData(int[] pixels, int width, int height)
{
this.pixels = pixels;
this.width = width;
this.height = height;
}
public PixelData(int width, int height)
{
this(new int[width * height], width, height);
}
public static PixelData createPixelData(String filename)
throws java.io.IOException
{
Image img = Image.createImage(filename);
int[] pixels = new int[img.getWidth() * img.getHeight()];
img.getRGB(pixels, 0, img.getWidth(), 0, 0, img.getWidth(), img.getHeight());
return new PixelData(pixels, img.getWidth(), img.getHeight());
}
private int index(int x, int y)
{
return y * this.width + x;
}
public int getPixel(int x, int y)
{
// 座標値を画像の中に収める
if (x < 0) x = 0;
if (x >= this.getWidth()) x = this.getWidth() - 1;
if (y < 0) y = 0;
if (y >= this.getHeight()) y = this.getHeight() - 1;
return this.pixels[index(x, y)];
}
private int bilinearColorInterpolate(int c1, int c2, double p)
{
// p*c2 + (1 - p)*c1
int r1 = (c1 >> 16) & 0xff;
int g1 = (c1 >> 8) & 0xff;
int b1 = (c1 >> 0) & 0xff;
int r2 = (c2 >> 16) & 0xff;
int g2 = (c2 >> 8) & 0xff;
int b2 = (c2 >> 0) & 0xff;
double r = p*r2 + (1 - p)*r1;
if (r < 0) r = 0;
if (r > 255) r = 255;
double g = p*g2 + (1 - p)*g1;
if (g < 0) g = 0;
if (g > 255) g = 255;
double b = p*b2 + (1 - p)*b1;
if (b < 0) b = 0;
if (b > 255) b = 255;
return ((int)r << 16) | ((int)g << 8) | (int)b;
}
public int getPixelBilinear(double x, double y)
{
// | : |
// y1----------------------
// q| : |q
// y*....o......%.....o....
// | p : 1-p |
// 1-q| : |1-q
// | : |
// y2----------------------
// | : |
// x1 x x2
//
// p = x* - x1, q = y* - y1
//
// f(x1, y*) = q*f(x1, y2) + (1-q)*f(x1, y1)
// f(x2, y*) = q*f(x2, y2) + (1-q)*f(x2, y1)
//
// f(x*, y*) = p*f(x2, y*) + (1-p)*f(x1, y*)
// = pq*f(x2, y2) + p(1-q)*f(x2, y1) +
// (1-p)q*f(x1, y2) + (1-p)(1-q)*f(x1, y1)
int x1 = (int)x;
int y1 = (int)y;
double p = x - x1;
double q = y - y1;
int c11 = getPixel(x1, y1);
int c12 = getPixel(x1, y1 + 1);
int c21 = getPixel(x1 + 1, y1);
int c22 = getPixel(x1 + 1, y1 + 1);
int r11 = (c11 >> 16) & 255;
int r12 = (c12 >> 16) & 255;
int r21 = (c21 >> 16) & 255;
int r22 = (c22 >> 16) & 255;
int r = (int)(p*q*r22 + p*(1-q)*r21 +
(1-p)*q*r12 + (1-p)*(1-q)*r11);
if (r < 0) r = 0; else if (r > 255) r = 255;
int g11 = (c11 >> 8) & 255;
int g12 = (c12 >> 8) & 255;
int g21 = (c21 >> 8) & 255;
int g22 = (c22 >> 8) & 255;
int g = (int)(p*q*g22 + p*(1-q)*g21 +
(1-p)*q*g12 + (1-p)*(1-q)*g11);
if (g < 0) g = 0; else if (g > 255) g = 255;
int b11 = (c11 >> 0) & 255;
int b12 = (c12 >> 0) & 255;
int b21 = (c21 >> 0) & 255;
int b22 = (c22 >> 0) & 255;
int b = (int)(p*q*b22 + p*(1-q)*b21 +
(1-p)*q*b12 + (1-p)*(1-q)*b11);
if (b < 0) b = 0; else if (b > 255) b = 255;
return (r << 16) | (g << 8) | b;
}
public void setPixel(int x, int y, int v)
{
// 座標値が画像内だったらピクセルをセットする
if (0 <= x && x <= this.getWidth() - 1 &&
0 <= y && y <= this.getHeight() - 1)
this.pixels[index(x, y)] = v;
}
public int getWidth() { return this.width; }
public int getHeight() { return this.height; }
public Image createRGBImage()
{
return Image.createRGBImage(this.pixels, this.width, this.height, false);
}
// fill a given rectangle area
//
// @param x x-coordinate of the filling rectangle
// @param y y-coordinate of the filling rectangle
// @param w width of the filling rectangle
// @param h height of the filling rectangle
// @param c fill color
public void fillRect(int x, int y, int w, int h, int c)
{
for (int i = 0; i < h && i + y < getHeight(); ++i) {
for (int j = 0; j < w && j + x < getWidth(); ++j) {
this.pixels[index(j + x, i + y)] = c;
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment