我正在开发Java中的图片转换实现。到目前为止,我已经实现了以下类:
在测试程序时,我注意到了一些奇怪的行为:
我已在public static Vector multiply(Matrix a, Vector v);
中修复了算法中的一些错误,因此乘法应该按预期工作。
在解决这些问题几个小时后,我不知道如何解决这个问题。任何帮助将不胜感激!
我希望发布整个代码是可以的,因为我不确定哪些部分有助于解决错误。
这些是类:
窗口:
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.FileDialog;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.MediaTracker;
import java.awt.event.ActionEvent;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.image.MemoryImageSource;
import java.awt.image.PixelGrabber;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Window extends JFrame {
Matrix m;
Window(int x, int y){
setBounds(20, 20, x, y);
final JPanel p = new JPanel();
p.setLayout(new BorderLayout());
Image img;
int[] pix;
MemoryImageSource m_ImgSrc;
FileDialog diag = new FileDialog(this);
diag.setVisible(true);
img = getToolkit().getImage(diag.getDirectory()+diag.getFile());
// getScaledInstance(x,y, Image.SCALE_SMOOTH);
diag.setFile("");
MediaTracker mt = new MediaTracker(this);
mt.addImage(img,0);
try {
mt.waitForAll();
} catch (InterruptedException e) {
e.printStackTrace();
}
Picture bild = new Picture(img);
PictureTransformer g = new PictureTransformer(bild);
p.add(g);
add(p, BorderLayout.CENTER);
g.repaint();
setVisible(true);
p.addMouseListener(new MouseListener(){
public void mouseClicked(MouseEvent arg0) {
System.out.println("Mouse-Event");
m = Matrix.rotate(45.0); //perform rotation by 45°
// System.out.println(m.v[0][0]);
g.transform(m);
p.repaint();
}
});
}
public static void main(String[] args) {
new Window(640, 480);
}
}
PictureTransformer:
import java.awt.Graphics;
import javax.swing.JComponent;
public class PictureTransformer extends JComponent{
Picture p;
PictureTransformer(Picture p){
this.p = p;
}
@Override
public void paintComponent(Graphics g){
g.drawImage(p.getImage(), 0, 0, 640, 480, this);
}
public void transform(Matrix t){ //p.W/p.H = Dimensions of the current picture to transform
int[] mPixelsResult = new int[p.getPixels().length]; //The temporary array contains the transformed pixels.
for(int x = 0; x < p.W; ++x){
for(int y = 0; y < p.H; ++y){
Vector v = Matrix.multiply(t, new Vector(x, y)); //Generates a Vector with new x- and y- values.
if(v.getVectorX() >= 0 && v.getVectorY() >= 0 && v.getVectorX() < p.W && v.getVectorY() < p.H){
mPixelsResult[p.W* y + x] = p.getPixels()[p.W * v.getVectorY() + v.getVectorX()]; //Stores the pixels at their new location.
}else{
mPixelsResult[p.W * y + x] = 0xFF000000; //Paint the background black, if not covered by the transformed picture.
}
}
}
p.setPixels(mPixelsResult); //Overwrite the original pixel-array with the temporary values.
p.mImage = createImage(p.mImgSrc);
p.mImage.flush();
repaint();
}
}
图片:
import java.awt.*;
import java.awt.image.*;
public class Picture {
int[] mPixels;
MemoryImageSource mImgSrc;
Image mImage;
final int W = 640; final int H = 480;
public Picture(Image img)
{
mImage = img;
mPixels = new int[W*H];
PixelGrabber pg = new PixelGrabber(mImage ,0,0,W,H,mPixels,0,W);
try {
pg.grabPixels();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(mPixels);
mImgSrc = new MemoryImageSource(W,H,mPixels,0,W);
}
public int[] getPixels()
{
return this.mPixels;
}
public Image getImage()
{
return this.mImage;
}
public void setPixels(int[] newPix)
{
this.mPixels = newPix;
}
public void setImage(Image newImg)
{
this.mImage = newImg;
}
}
矩阵
public class Matrix {
double[][] v;
Matrix(double[][] v){
this.v = v;
}
/** Creates an Matrix that will used to translate the picture to the coordinates
* clicked on the screen.
**/
public static Matrix translate(int dx, int dy){
double dM[][] = {{1, 0, 0}, {0, 1, 0}, {Math.round(-dx), Math.round(-dy), 1}};
return new Matrix(dM);
}
public static Matrix rotate(double a){
double rad = -(Math.PI * a / 180);
double dM[][] = {{Math.cos(rad), Math.sin(rad), 0},{Math.sin(rad), Math.cos(rad), 0}, {0, 0, 1}};
return new Matrix(dM);
}
/** Creates an Matrix that will used to scale the picture by the given factor. **/
public static Matrix scale(double f){
double dM[][] = {{1/f, 0, 0}, {0, 1/f, 0}, {0, 0, 1}};
return new Matrix(dM);
}
public static Matrix shearX(double sX){
double dM[][] = {{1, 0, 0}, {-sX, 1, 0}, {0, 0, 1}};
return new Matrix(dM);
}
public static Matrix shearY(double sY){
double dM[][] = {{1, -sY, 0}, {0, 1, 0}, {0, 0, 1}};
return new Matrix(dM);
}
public static Matrix multiply(Matrix x, Matrix y){
double[][] p = new double[3][3];
for(int i = 0; i < x.v.length; ++i){
for(int j = 0; j < x.v[i].length; j++){
for(int k = 0; k < 3; k++){
p[i][j] += + x.v[k][j] * y.v[i][k];
}
}
}
return new Matrix(p);
}
public static Vector multiply(Matrix a, Vector v){
int[] res = new int[a.v[0].length];
for(int i = 0; i < a.v[0].length; i++){
for(int j = 0; j < a.v.length; j++){
/* Multiplying the Vector with the Matrix.
* (x) [a d g] (a) (d) (g)
* (y) * [b e h] = x * (b) + y * (e) + z * (h)
* (z) [c f i] (c) (f) (i)
* (x*a + y*d + z*g)
* = (x*b + y*e + z*h)
* (x*c + y*f + z*i)
*/
res[i] += a.v[i][j] * v.getVector(j);
}
}
Vector r = new Vector(res[0], res[1]); //Copying the result which represents the new pixel location into an Vector
return r;
}
}
矢量
public class Vector {
private int[] v;
Vector(int x, int y){
v = new int[3]; //We'll always have a 3 Vector...
v[0] = x;
v[1] = y;
v[2] = 1;
// System.out.println("NEW VECTOR " + v[0] + " "+ v[1]);
}
Vector(){
v = new int[3];
v[0] = 0;
v[1] = 0;
v[2] = 1;
}
public int getVectorX(){
return v[0];
}
public int getVectorY(){
return v[1];
}
public int getVectorZ(){
return v[2];
}
public void setVector(int i, double d){
v[i] = (int)d;
}
public int getVector(int i){
return v[i];
}
public void setVectorX(int i){
v[0] = i;
}
public void setVectorY(int i){
v[1] = i;
}
}
答案 0 :(得分:1)
我发现两件事,在Matrix类中,我改变了旋转矩阵:
public static Matrix rotate(final double a) {
final double rad = Math.PI * a / 180;
final double dM[][] = { { Math.cos(rad), Math.sin(rad), 0 }, { -Math.sin(rad), Math.cos(rad), 0 }, { 0, 0, 1 } };
return new Matrix(dM);
}
在PictureTransformer类转换方法中,我以不同的方式执行新的图像创建:
// p.mImage = createImage(p.mImgSrc);
final MemoryImageSource mis = new MemoryImageSource(p.W, p.H, mPixelsResult, 0, p.W);
final Toolkit tk = Toolkit.getDefaultToolkit();
p.mImage = tk.createImage(mis);
p.mImage.flush();
结果是图像在窗口中旋转-45º。 这不是解决方案,而是一个起点。
希望有所帮助。