24. oktober 2001 - 14:47
Der er
7 kommentarer og
1 løsning
Dreje et billede i java 2
Jeg skal haved det lavet sådan at et billede skal dreje om sin egen akse. Når jeg klikker på en knap, skal den dreje en smule om sin akse, og næste gang jeg klikker igen en lille smule osv. Hvordan kan man gøre dette.
24. oktober 2001 - 14:56
#3
Du skal bruge et image filter, ala dette her:
import java.awt.image.ColorModel;
import java.awt.image.ImageFilter;
import java.util.Hashtable;
import java.awt.Rectangle;
public class RotateFilter extends ImageFilter {
private static ColorModel defaultRGB = ColorModel.getRGBdefault();
private double angle;
private double sin;
private double cos;
private double coord[] = new double[2];
private int raster[];
private int xoffset, yoffset;
private int srcW, srcH;
private int dstW, dstH;
public RotateFilter(double angle) {
this.angle = angle;
sin = Math.sin(angle);
cos = Math.cos(angle);
}
public void transform(double x, double y, double[] retcoord) {
// Remember that the coordinate system is upside down so apply
// the transform as if the angle were negated.
// cos(-angle) = cos(angle)
// sin(-angle) = -sin(angle)
retcoord[0] = cos * x + sin * y;
retcoord[1] = cos * y - sin * x;
}
public void itransform(double x, double y, double[] retcoord) {
// Remember that the coordinate system is upside down so apply
// the transform as if the angle were negated. Since inverting
// the transform is also the same as negating the angle, itransform
// is calculated the way you would expect to calculate transform.
retcoord[0] = cos * x - sin * y;
retcoord[1] = cos * y + sin * x;
}
public void transformBBox(Rectangle rect) {
double minx = Double.POSITIVE_INFINITY;
double miny = Double.POSITIVE_INFINITY;
double maxx = Double.NEGATIVE_INFINITY;
double maxy = Double.NEGATIVE_INFINITY;
for (int y = 0; y <= 1; y++) {
for (int x = 0; x <= 1; x++) {
transform(rect.x + x * rect.width,
rect.y + y * rect.height,
coord);
minx = Math.min(minx, coord[0]);
miny = Math.min(miny, coord[1]);
maxx = Math.max(maxx, coord[0]);
maxy = Math.max(maxy, coord[1]);
}
}
rect.x = (int) Math.floor(minx);
rect.y = (int) Math.floor(miny);
rect.width = (int) Math.ceil(maxx) - rect.x + 1;
rect.height = (int) Math.ceil(maxy) - rect.y + 1;
}
public void setDimensions(int width, int height) {
Rectangle rect = new Rectangle(0, 0, width, height);
transformBBox(rect);
xoffset = -rect.x;
yoffset = -rect.y;
srcW = width;
srcH = height;
dstW = rect.width;
dstH = rect.height;
raster = new int[srcW * srcH];
consumer.setDimensions(dstW, dstH);
}
public void setColorModel(ColorModel model) {
consumer.setColorModel(defaultRGB);
}
public void setHints(int hintflags) {
consumer.setHints(TOPDOWNLEFTRIGHT
| COMPLETESCANLINES
| SINGLEPASS
| (hintflags & SINGLEFRAME));
}
public void setPixels(int x, int y, int w, int h, ColorModel model,
byte pixels[], int off, int scansize) {
int srcoff = off;
int dstoff = y * srcW + x;
for (int yc = 0; yc < h; yc++) {
for (int xc = 0; xc < w; xc++) {
raster[dstoff++] = model.getRGB(pixels[srcoff++] & 0xff);
}
srcoff += (scansize - w);
dstoff += (srcW - w);
}
}
public void setPixels(int x, int y, int w, int h, ColorModel model,
int pixels[], int off, int scansize) {
int srcoff = off;
int dstoff = y * srcW + x;
if (model == defaultRGB) {
for (int yc = 0; yc < h; yc++) {
System.arraycopy(pixels, srcoff, raster, dstoff, w);
srcoff += scansize;
dstoff += srcW;
}
} else {
for (int yc = 0; yc < h; yc++) {
for (int xc = 0; xc < w; xc++) {
raster[dstoff++] = model.getRGB(pixels[srcoff++]);
}
srcoff += (scansize - w);
dstoff += (srcW - w);
}
}
}
public void imageComplete(int status) {
if (status == IMAGEERROR || status == IMAGEABORTED) {
consumer.imageComplete(status);
return;
}
int pixels[] = new int[dstW];
for (int dy = 0; dy < dstH; dy++) {
itransform(0 - xoffset, dy - yoffset, coord);
double x1 = coord[0];
double y1 = coord[1];
itransform(dstW - xoffset, dy - yoffset, coord);
double x2 = coord[0];
double y2 = coord[1];
double xinc = (x2 - x1) / dstW;
double yinc = (y2 - y1) / dstW;
for (int dx = 0; dx < dstW; dx++) {
int sx = (int) Math.round(x1);
int sy = (int) Math.round(y1);
if (sx < 0 || sy < 0 || sx >= srcW || sy >= srcH) {
pixels[dx] = 0;
} else {
pixels[dx] = raster[sy * srcW + sx];
}
x1 += xinc;
y1 += yinc;
}
consumer.setPixels(0, dy, dstW, 1, defaultRGB, pixels, 0, dstW);
}
consumer.imageComplete(status);
}
}
24. oktober 2001 - 14:59
#5
Du bruger det iøvrigt sådan her:
Image sourceImage = .... // your image loaded some how.
ImageFilter filter = new RotateFilter(2.5); // degree rotation specified
ImageProducer producer = new FilteredImageSource(sourceImage.getSource(),filter);
Image resultImage = createImage(producer);
Og så er det resultImage, som du tegner.