java中图片与像素矩阵转换,java - Java中具有矩阵乘法的图片转换不起作用 - 堆栈内存溢出...

我正在用Java实现图片转换。 到目前为止,我已经实现了以下类:

矩阵 (持有一个3x3矩阵,该矩阵将用于与Vector相乘)

向量 (用于与变换矩阵相乘以生成原始图像像素的新位置)

PictureTransformer (转换Image并将新值存储到临时数组)

图片 (保存Image mImage和pixel数组mPixels的成员变量,并提供getter和setter方法)

Window (用于测试功能的临时类,因为这些类将是较大程序的一部分)

在测试程序时,我注意到一些奇怪的行为:

无论我使用哪种转换,图片始终在缩放

无论我多久触发一次MouseEvent,转换都只会执行一次

我已经修复了public static Vector multiply(Matrix a, Vector v);算法中的一些错误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
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值