程序运行出现Exception in thread "AWT-EventQueue-0" java.lang.ArrayIndexOutOfBoundsException: -1如何处理?

熵增- 发布于 2016/06/02 22:16
阅读 18K+
收藏 0
用eclipse运行如下程序,没有错误可以正常运行,这是一个两张照片融合的程序,但是运行后无法得到结果,出现错误如图,不知道如何处理,求大神QAQ 程序比较长...实在是不知道怎么办了..
package myMorphing95;
import java.io.*;
import java.lang.*;
import java.util.*;
import java.awt.event.*;
import java.awt.*;
import java.awt.image.*;
import java.beans.IntrospectionException;
import javax.imageio.stream.MemoryCacheImageInputStream;
import javax.swing.*;



/*
 1.定义myMorphingPanel95类,实现Runnable接口
 */
class myMorphingPanel95 extends Panel implements Runnable
{
    String sName,dName;
    Thread thread;
    int w,h;
    Panel pdown = new Panel();
    Checkbox check1,check2;
    TextField t1,t2;
    Label L1,L2;
    Button wbutton;
    BorderLayout borderLayout = new BorderLayout();
    ColorModel defaultRGB=ColorModel.getRGBdefault();
    int x0;
    int y0;
    int xx;
    int yy;
    int x1;
    int y1;
    int i;
    int j;
    int block;
    int belongCenter;
    int flag=-1;
    Image bgim,im1,im2,im3,im4,im5,im6;
    int[] pixels1,pixels2,pixels3,pixels4,pixels5,pixels6;

    /*
     * 定义和初始化控制顶点、控制网络、中心顶点的坐标数组和控制序列数组
     */
    Point[] source=new Point[81];
    Point[] middle=new Point[81];
    Point[] destination=new Point[81];
    Point[] [] s=new Point[64][4];
    Point[] [] m=new Point[64][4];
    Point[] [] d=new Point[64][4];
    Point[] scenter=new Point[49];
    Point[] mcenter=new Point[49];
    Point[] dcenter=new Point[49];
    int[] weights=new int[64];
    /*
     * 源图像控制网格顶点的控制序列
     */
    int[] weightd=new int[64];
    /*
     * 目标图像控制网格顶点的控制序列
     */
    int[] weightsp=new int[81];
    /*
     * 源图像控制网格的控制序列
     */
    int[] weightdp=new int[81];
    /*
     * 目标图像控制网格的控制序列
     */
    Point press,move;
    Point p=new Point();
    Point q=new Point();
    Point q1=new Point();
    Point q2=new Point();

    /*2.定义myMorphingPanel95的构造器,
    在构造器中添加面板pdown,
    在pdown上添加单选按钮,
    并在单选按钮后添加标签条、按钮、文本框等,
    用于修改控制序列。装载图像、定义控制网格,
    添加鼠标下压、鼠标拖动事件监听,添加单选按钮事件监听和按钮事件监听
     */
    public myMorphingPanel95(String sName,String dName)
    {
        this.sName=sName;
        /*
        源图像文件名
        */
        this.dName=dName;
        /*
         * 目标图像文件名
         */
        this.setLayout(borderLayout);
        this.setSize(650,600);
        t1=new TextField();
        t2=new TextField();
        L1=new Label();
        L2=new Label();
        wbutton=new Button("修改");
        CheckboxGroup g=new CheckboxGroup();
        check1=new Checkbox("特征意义",false,g);
        check2=new Checkbox("控制意义",false,g);
        L1.setText("区域:");
        t1.setText("0");
        L2.setText("控制值:");
        t2.setText("1");
        pdown.setBackground(Color.pink);
        this.add(pdown,BorderLayout.SOUTH);
        pdown.add(check1);
        pdown.add(check2);
        pdown.add(L1);
        pdown.add(t1);
        pdown.add(L2);
        pdown.add(t2);
        pdown.add(wbutton);

        /*
         * 装载源图像,并抓取像素到pixles1
         */
        MediaTracker tracker=new MediaTracker(this);
        bgim=Toolkit.getDefaultToolkit().getImage("bg.jpg");
        tracker.addImage(bgim,0);
        try
        {
            tracker.waitForID(0);
        }
        catch (InterruptedException e)
        {
            e.printStackTrace();
        }
        if(sName==null)
            sName="liu2.jpg";
        im1=Toolkit.getDefaultToolkit().getImage(sName);
        tracker.addImage(im1,0);
        try
        {
            tracker.waitForID(0);
        }
        catch (InterruptedException e)
        {
            e.printStackTrace();
        }
        w=im1.getWidth(this);
        h=im1.getHeight(this);

        /*
         * 初始化各个图像像素数组
         */
        pixels1=new int[w*h];
        pixels2=new int[w*h];
        pixels3=new int[w*h];
        pixels4=new int[w*h];
        pixels5=new int[w*h];
        pixels6=new int[w*h];
        try
        {
            PixelGrabber pg = new PixelGrabber(im1,0,0,w,h,pixels1,0,w);
            pg.grabPixels();
        }
        catch (InterruptedException e)
        {
            e.printStackTrace();
        }

        /*
         * 装载目标图像,并抓取像素到pixles2
         */
        if(dName==null)
            dName="te2.jpg";
        im2=Toolkit.getDefaultToolkit().getImage(dName);
        tracker.addImage(im2,0);
        try
        {
            tracker.waitForID(0);
        }
        catch (InterruptedException e)
        {
            e.printStackTrace();
        }
        try
        {
            PixelGrabber pg = new PixelGrabber(im2,0,0,w,h,pixels2,0,w);
            pg.grabPixels();
        }
        catch (InterruptedException e)
        {
            e.printStackTrace();
        }

        /*
         * 定义控制点
         */
        for(i=0;i<9;i++)
        {
            for (j=0;j<9;j++)
            {
                source[i*9+j]=new Point(w/8*j,h/8*i);
                middle[i*9+j]=new Point(source[i*9+j].x+5+w,source[i*9+j].y);
                destination[i*9+j]=new
                        Point(source[i*9+j].x+10+w*2,source[i*9+j].y);
            }
        }

        for(i=0;i<8;i++)
        {
            for (j=0;j<8;j++)
            {
                s[i*8+j][0]=source[i*8+j+i];
                s[i*8+j][1]=source[i*8+j+i+1];
                s[i*8+j][2]=source[i*8+j+i+1+9];
                s[i*8+j][3]=source[i*8+j+i+9];
                m[i*8+j][0]=middle[i*8+j+i];
                m[i*8+j][1]=middle[i*8+j+i+1];
                m[i*8+j][2]=middle[i*8+j+i+1+9];
                m[i*8+j][3]=middle[i*8+j+i+9];
                d[i*8+j][0]=destination[i*8+j+i];
                d[i*8+j][1]=destination[i*8+j+i+1];
                d[i*8+j][2]=destination[i*8+j+i+1+9];
                d[i*8+j][3]=destination[i*8+j+i+9];
            }
        }

        for (i=1;i<8;i++)
        {
            for (j=1;j<8;j++)
            {
                scenter[i*7+j-8]=source[i*9+j];
                mcenter[i*7+j-8]=middle[i*9+j];
                dcenter[i*7+j-8]=destination[i*9+j];
            }
        }

        for(i=0;i<weights.length;i++)
        {
            weights[i]=1;
        }
        /*
         * ===定义块控制值(源)
         */
        for(i=0;i<weightd.length;i++)
        {
            weightd[i]=1;
        }
        /*
         * ===定义块控制值(目标)
         */
        for(i=0;i<weightsp.length;i++)
        {
            weightsp[i]=1;
        }
        /*
         * ===定义点控制值(源)
         */
        for(i=0;i<weightdp.length;i++)
        {
            weightdp[i]=1;
        }
        /*
         * ===定义点控制值(目标)
         */


        /*
         * 监听鼠标下压事件,如果下压鼠标,运行panel_mousePressed()方法
         */
        addMouseListener(new MouseAdapter()
        {
            public void mousePressed(MouseEvent e)
            {
                panel_mousePressed(e);
            }
        }
        );

        /*
         * 监听鼠标拖动事件,如果拖动鼠标,运行panel_mouseDragged()方法
         */
        addMouseMotionListener(new MouseMotionAdapter()
        {
            public void mouseDragged (MouseEvent e)
            {
                panel_mouseDragged(e);
            }
        });

        /*
         * 监听单选按钮事件,如果选择check1“特定定义”,设置flag=0,并且文本输入框不可用
         */
        check1.addItemListener(new ItemListener()
        {
            public void itemStateChanged(ItemEvent event)
            {
                if(check1.getState())
                {
                    t1.setEnabled(false);
                    L1.setEnabled(false);
                    t2.setEnabled(false);
                    L2.setEnabled(false);
                    flag=0;
                    repaint();
                }
            }
        });

        /*
         * 监听单选按钮事件,如果选择check1【控制定义】,设置flag=2,并且文本输入框可用
         */
        check2.addItemListener(new ItemListener()
        {
            public void itemStateChanged(ItemEvent event)
            {
                if(check2.getState())
                {
                    t1.setEnabled(true);
                    L1.setEnabled(true);
                    t2.setEnabled(true);
                    L2.setEnabled(true);
                    flag=2;
                    repaint();
                }
            }
        });

        /*
         * 监听按钮事件,如果选择单击按钮wbutton“修改”,运行方法wbutton_actionPerformed()
         */
        wbutton.addActionListener(new java.awt.event.ActionListener()
        {
            public void actionPerformed(ActionEvent e)
            {
                wbutton_actionPerformed(e);
            }
        });
    }


    /*3.定义panel_mousePressed()方法,
    如果用户点技术表,首先判断flag的值,
    如果flag为0,则表明要进行【特征定义】操作,
    方法同8.3.如果flag为1,表明要进行【控制定义】,
    具体操作为:判断用户单击处属于哪一种网格,
    然后将文本框显示为这个网格的编号
     */
    public void panel_mousePressed(MouseEvent e)
    {
        if(flag==0)
        {
            Graphics g =getGraphics();
            x1=-1;
            y1=-1;
            x0=e.getX();
            y0=e.getY();
            press=new Point(x0,y0);
            if(x0>w)
                belongCenter=belongs(press,dcenter,destination);
            else
                belongCenter=belongs(press,scenter,source);
            if(belongCenter!=-1)
                x1=x0;
            y1=y0;
        }

        if(flag==2)
        {
            xx=e.getX();
            yy=e.getY();
            press=new Point(xx,yy);
            if(xx>w)
            {
                block=containP(press,d);
                t1.setText(Integer.toString(block)+"右图");
                t2.setText(Integer.toString(weightd[block]));
            }
            else
            {
                block=containP(press,s);
                t1.setText(Integer.toString(block)+"左图");
                t2.setText(Integer.toString(weights[block]));
            }
        }
    }
    /*
     * 4.定义panel_mouseDragged()方法,如果发生鼠标拖动事件,
     * 修改源图像像素数组/目标图像像素数组为鼠标移动的坐标位置
     */
    public void panel_mouseDragged(MouseEvent e){
        Graphics graphics=getGraphics();
        x1=e.getX();y1=e.getY();
        if(x0<w){
            source[belongCenter].x=x1;
            source[belongCenter].y=y1;
            repaint();
        }
        else {
            destination[belongCenter].x=x1;
            destination[belongCenter].y=y1;
            repaint();
        }
    }
    /* 5.定义process_actionPerformed()方法,当用户点击运行菜单里的运行时,
     * 首先计算中间图像网格的控制顶点
      然后对中间图像的每一个点P计算它在源图像和目标图像中的对应点q1和q2,
      根据q1和q2比例不同
      可以产生3个图像im4、im5、im6,
      im2为在控制序列作用下产生的中间图像
      */
    public void process_actionPerformed(){
        for(i=0;i<scenter.length;i++){
            int ttt=i+(i-i%7)/7*2+10;
            mcenter[i].x=(scenter[i].x+w+5)*weightsp[ttt]/(weightsp[ttt]+weightdp[ttt])+(dcenter[i].x-w-5)*weightdp[ttt]/(weightsp[ttt]+weightdp[ttt]);
            mcenter[i].y=scenter[i].y*weightsp[ttt]/(weightsp[ttt]+weightdp[ttt])+scenter[i].y*weightdp[ttt]/(weightsp[ttt]+weightdp[ttt]);
        }
        for(j=0;j<=(w*h-1);j++){
            p.x=(int)j%w;
            p.y=(int)(j-p.y)/w;
            block=containP(new Point(p.x+5+w,p.y),m);
            for(i=0;i<4;i++)
                m[block][i].x=m[block][i].x-w-5;
            q1=cal(p,m[block][0],m[block][1],m[block][2],m[block][3],s[block][0],s[block][1],s[block][2],s[block][3],block);
            for(i=0;i<4;i++)
                m[block][i].x=m[block][i].x+w+5;
            for(i=0;i<4;i++){
                m[block][i].x=m[block][i].x-w-5;
                d[block][i].x=d[block][i].x-2*w-10;
            }
            q2=cal(p,m[block][0],m[block][1],m[block][2],m[block][3],d[block][0],d[block][1],d[block][2],d[block][3],block);
            for(i=0;i<4;i++){
                m[block][i].x=m[block][i].x+w+5;
                d[block][i].x=d[block][i].x+2*w+10;
            }
            int tt1=q1.y*w+q1.x;
            int tt2=q2.y*w+q2.x;
            if(tt1<=(w*h-1)||tt2<=(w*h-1)){
                int r0=defaultRGB.getRed(pixels1[q1.y*w+q1.x]);
                int r2=defaultRGB.getRed(pixels1[q2.y*w+q2.x]);
                int g0=defaultRGB.getGreen(pixels1[q1.y*w+q1.x]);
                int g2=defaultRGB.getGreen(pixels1[q2.y*w+q2.x]);
                int b0=defaultRGB.getBlue(pixels1[q1.y*w+q1.x]);
                int b2=defaultRGB.getBlue(pixels1[q2.y*w+q2.x]);
                int r=(r0+r2)/2;
                int g=(g0+g2)/2;
                int b=(b0+b2)/2;
                if((weights[block]+weightd[block]!=0)){
                    int rr=r0*weights[block]/(weights[block]+weightd[block])+r2*weightd[block]/(weights[block]+weightd[block]);
                    int gg=g0*weights[block]/(weights[block]+weightd[block])+g2*weightd[block]/(weights[block]+weightd[block]);
                    int bb=b0*weights[block]/(weights[block]+weightd[block])+b2*weightd[block]/(weights[block]+weightd[block]);
                    pixels3[j]=0xff<<24 | rr<<16 | gg<<8 |bb;

                }
                pixels4[j]=0xff<<24|(r0*3/4+r2/4)<<16|(g0*3/4+g2/4)<<8|(b0*3/4+b2/4);
                pixels6[j]=0xff<<24|(r2*3/4+r0/4)<<16|(g2*3/4+g0/4)<<8|(b2*3/4+b0/4);
                pixels5[j]=0xff<<24 | r<<16 | g<<8 |b;
            }
        }
        ImageProducer ip3 =new MemoryImageSource(w, h, pixels3, 0, w);
        im3=createImage(ip3);
        ImageProducer ip4 =new MemoryImageSource(w, h, pixels4, 0, w);
        im3=createImage(ip4);
        ImageProducer ip5 =new MemoryImageSource(w, h, pixels5, 0, w);
        im3=createImage(ip5);
        ImageProducer ip6 =new MemoryImageSource(w, h, pixels6, 0, w);
        im3=createImage(ip6);
        repaint();
    }
    /*
     * 6.定义tt()方法。当用户选择运行菜单中的运行动画时,
     * 将运行tt()方法,该方法计算中间图像的控制网格,
     * 然后启动线程
     */
    public void tt(){
        for(i=0;i<scenter.length;i++)
        {
            mcenter[i].x=(scenter[i].x+dcenter[i].x)/2;
            mcenter[i].y=(scenter[i].y+dcenter[i].y)/2;
        }
        thread=new Thread(this);
        thread.start();
    }
    /*
     * 7.定义run()方法,首先计算p的对应点q1和q2,
     * 然后将整个渐变过程分为51帧,用repaint()方法刷新屏幕播放动画
     */
    public void run(){
        int j,frame,block;
        int[] temp1=new int[w*h-1];
        int[] temp2=new int[w*h-1];
        for(j=0;j<w*h-1;j++){
            p.x=(int)j%w;
            p.y=(int)(j-p.x)/w;
            block=containP(new Point(p.x+5+w,p.y),m);
            for(i=0;i<4;i++)
                m[block][i].x=m[block][i].x-w-5;
            q1=cal(p,m[block][0],m[block][1],m[block][2],m[block][3],s[block][0],s[block][1],s[block][2],s[block][3],block);
            for(i=0;i<4;i++)
                m[block][i].x=m[block][i].x+w+5;
            for(i=0;i<4;i++){
                m[block][i].x=m[block][i].x-w-5;
                d[block][i].x=d[block][i].x-2*w-10;
            }
            q2=cal(p,m[block][0],m[block][1],m[block][2],m[block][3],d[block][0],d[block][1],d[block][2],d[block][3],block);
            for(i=0;i<4;i++){
                m[block][i].x=m[block][i].x+w+5;
                d[block][i].x=d[block][i].x+2*w+10;
            }
            int tt1=q1.y*w+q1.x;
            int tt2=q2.y*w+q2.x;
            if(tt1<w*h-1||tt2<=w*h-1){
                temp1[j]=pixels1[tt1];
                temp2[j]=pixels2[tt2];
            }

        }
        for(frame=0;frame<51;frame++){
            for(j=0;j<w*h-1;j++){
                int r0=defaultRGB.getRed(temp1[j]);
                int r2=defaultRGB.getRed(temp2[j]);
                int r1=(int)((r0+r2)/2);
                int g0=defaultRGB.getRed(temp1[j]);
                int g2=defaultRGB.getRed(temp2[j]);
                int g1=(int)((g0+g2)/2);
                int b0=defaultRGB.getRed(temp1[j]);
                int b2=defaultRGB.getRed(temp2[j]);
                int b1=(int)((b0+b2)/2);
                int r=r0*(51-frame)/51+r2*frame/51;
                int g=g0*(51-frame)/51+g2*frame/51;
                int b=b0*(51-frame)/51+b2*frame/51;
                pixels3[j]=0xff<<24|r<<16|g<<8|b;

            }
            ImageProducer ip3 =new MemoryImageSource(w, h, pixels3,0, w);
            im3=createImage(ip3);
            try{thread.sleep(50);}
            catch(Exception e){}
            repaint();

        }
    }
    /*
     * 8.定义wbutton_actionPerformed()方法,
     * 当用户单击pdown上的按钮【修改】时,
     * 修改控制序列数组中相应的值
     */
    public void wbutton_actionPerformed(ActionEvent e) {
        if(flag==2){
            if(xx>w){
                weightd[block]=Integer.parseInt(t2.getText());
                weightdp[block+(block-(block%8))/8]=Integer.parseInt(t2.getText());
                weightdp[block+(block-(block%8))/8+1]=Integer.parseInt(t2.getText());
                weightdp[block+(block-(block%8))/8+9]=Integer.parseInt(t2.getText());
                weightdp[block+(block-(block%8))/8+10]=Integer.parseInt(t2.getText());
            }
            else {
                weights[block]=Integer.parseInt(t2.getText());
                weightsp[block+(block-(block%8))/8]=Integer.parseInt(t2.getText());
                weightsp[block+(block-(block%8))/8+1]=Integer.parseInt(t2.getText());
                weightsp[block+(block-(block%8))/8+9]=Integer.parseInt(t2.getText());
                weightsp[block+(block-(block%8))/8+10]=Integer.parseInt(t2.getText());
            }
        }

    }
    /*
     * 9.定义out_actionPerformed()方法,
     * 当用户选择编辑菜单中的输出特征值时,
     * 将当前源图像和目标图像的控制顶点数组输出到文本文件
     */
    public void out_actionPerformed(String sName,String dName){
        String outSfile,outDfile;
        outSfile="s("+sName+").txt";
        outSfile="d("+dName+").txt";
        try{
            PrintWriter outs =new PrintWriter(new BufferedWriter(new FileWriter(outSfile)));
            for(i=0;i<source.length;i++){
                outs.println(source[i].x+","+source[i].y);
            }
            outs.flush();
            outs.close();
            PrintWriter outd=new PrintWriter(new BufferedWriter(new FileWriter(outSfile)));
            for(i=0;i<destination.length;i++){
                outd.println(destination[i].x+","+destination[i].y);
            }
            outs.flush();
            outs.close();
        }catch(IOException exc){}

    }
    /*
     * 10.定义in_actionPerformed()方法,
     * 当用户选择编辑菜单中的输入特征值时,
     * 将从文本文件输入坐标值到源图像和目标图像的控制顶点数组中
     */
    public void in_actionPerformed(String sName,String dName){
        String s,d;
        String inSfile,inDfile;
        inSfile="s("+sName+").txt";
        inSfile="d("+dName+").txt";
        try{
            BufferedReader ins=new BufferedReader(new FileReader(inSfile));
            for(i=0;i<source.length;i++){
                s=ins.readLine();
                StringTokenizer ts=new StringTokenizer(s, ",");
                source[i].x=Integer.parseInt(ts.nextToken());
                source[i].y=Integer.parseInt(ts.nextToken());
            }
            ins.close();
            BufferedReader ind=new BufferedReader(new FileReader(inSfile));
            for(i=0;i<destination.length;i++){
                d=ind.readLine();
                StringTokenizer td=new StringTokenizer(d, ",");
                destination[i].x=Integer.parseInt(td.nextToken());
                destination[i].y=Integer.parseInt(td.nextToken());
            }
            ins.close();
        }catch(IOException exc){}
        repaint();
    }


    public int belongs(Point p,Point[] center,Point[] allPoint){
        Polygon b;
        int bcenter=-1;
        int scenter=-1;
        int[] x=new int[4];
        int[] y=new int[4];
        for(i=0;i<center.length;i++){
            x[0]=center[i].x-3;
            x[1]=center[i].x+3;
            x[2]=center[i].x+3;
            x[3]=center[i].x-3;
            y[0]=center[i].y-3;
            y[1]=center[i].y-3;
            y[2]=center[i].y+3;
            y[3]=center[i].y+3;
            b=new Polygon(x,y,4);
            if(b.contains(p.x,p.y))
                bcenter=i;

        }
        if(bcenter!=-1){
            for(i=0;i<allPoint.length;i++){
                if(center[bcenter]==allPoint[i])
                    scenter=i;
            }
        }
        return scenter;
    }
    /*
     * 12.定义containP()方法,
     * 判断点p属于哪一个控制区域;
     * 用网格的控制顶点组成矩形,
     * 判断p是否属于该矩形
     */
    public int containP(Point p,Point[][] m){
        int k=0,block=-1,flag=0;
        int[] xpoint=new int[4];
        int[] ypoint=new int[4];
        Polygon b;
        while(flag==0&k<64){
            xpoint[0]=m[k][0].x;
            xpoint[1]=m[k][1].x;
            xpoint[2]=m[k][2].x;
            xpoint[3]=m[k][3].x;
            ypoint[0]=m[k][0].y;
            ypoint[1]=m[k][1].y;
            ypoint[2]=m[k][2].y;
            ypoint[3]=m[k][3].y;
            b=new Polygon(xpoint,ypoint,4);
            if(b.contains(p.x,p.y)){
                block=k;
                flag=1;
            }
            if(p==m[k][0]|p==m[k][1]|p==m[k][2]|p==m[k][3]){
                block=k;
                flag=1;
            }
            k++;

        }
        return block;
    }
    /*
     * 13.定义cal()方法,
     * 依据双线性变换计算四边形ABCD中的Point p在四边形abcd中的对应点qd
     */
    public Point cal(Point p,Point A,Point B,Point C,Point D,Point a,Point b,Point c,Point d,int block){
        int i,a1,b1,c1,d1,a2,b2,c2,d2,b3,b4,c3,c4;
        double u,v,e1,f1,g1,e2,f2,g2,u1=0,u2=0;
        Point qd=new Point();
        a1=p.x-A.x;
        a2=p.y-A.y;
        b1=A.x-B.x;
        b2=A.y-B.y;
        b3=A.x-D.x;
        b4=A.y-D.y;
        c1=D.x-A.x;
        c2=D.y-A.y;
        c3=B.x-A.x;
        c4=B.y-A.y;
        d1=A.x-B.x+C.x-D.x;
        d2=A.y-B.y+C.y-D.y;
        e1=(b1*d2-d1*b2)/10000.0;
        e2=(b3*d2-d1*b4)/10000.0;
        f1=(a1*d2+b1*c2-a2*d1-c1*b2)/10000.0;
        f2=(a1*d2+b3*c4-a2*d1-c3*b4)/10000.0;
        g1=(a1*c2-a2*c1)/10000.0;
        g2=(a1*c4-a2*c3)/10000.0;
        if(e1==0)
            u=-g1/f1;
        else{
            u1=(-f1+Math.sqrt(f1*f1-4*e1*g1))/(2*e1);
            u2=(-f1-Math.sqrt(f1*f1-4*e1*g1))/(2*e1);
            if(u1>=0.000&u1<=1.000)
                u=u1;
            else
                u=u2;
        }
        if(e2==0)
            v=-g2/f2;
        else
            v=(a1+b1*u)/(c1+d1*u);
        if(u>=0&u<=1&v>=0&v<=1){
            qd.x=(int)((1-u)*(1-v)*a.x+u*(1-v)*b.x+u*v*c.x+(1-u)*v*d.x);
            qd.y=(int)((1-u)*(1-v)*a.y+u*(1-v)*b.y+u*v*c.y+(1-u)*v*d.y);

        }
        return qd;


    }
    /*
     * 14.重写update()方法,判断当im3、im4、im5、im6不为空时,绘制图像
     */
    public void update(Graphics g){
        paint(g);
        if(im3!=null)
            g.drawImage(im3,w+5,0,this);
        if(im4!=null)
            g.drawImage(im4,0,h+10,this);
        if(im5!=null)
            g.drawImage(im5,w+5,h+10,this);
        if(im6!=null)
            g.drawImage(im6,w*2+10,h+10,this);

    }
    /*
     * 15.重写paint()方法,绘制源图像和目标图像,绘制网格
     */
    public void paint(Graphics g){
        g.drawImage(im1,0,0,this);
        g.drawImage(im2,w*2+10,0,this);
        g.setColor(Color.green);
        for(i=0;i<9;i++){
            for(j=0;j<8;j++){
                g.drawLine(source[i*9+j].x,source[i*9+j].y,
                        source[i*9+j+1].x,source[i*9+j+1].y);
                g.drawLine(destination[i*9+j].x,destination[i*9+j].y,
                        destination[i*9+j+1].x,destination[i*9+j+1].y);
                g.drawLine(source[i+9*j].x,source[i+9*j].y,
                        source[i+9*j+9].x,source[i+9*j+9].y);
                g.drawLine(destination[i+9*j].x,destination[i+9*j].y,
                        destination[i+9*j+9].x,destination[i+9*j+9].y);

            }
        }
    }
}
/*
 * 16.定义myMorphing95类,实现ActionListener接口
 */
public class myMorphing95  extends Frame implements ActionListener{
    BorderLayout bLayout = new BorderLayout();
    MenuItem loadMenuItem,exitMenuItem,charMenuItem,weightMenuItem,
            outMenuItem,inMenuItem,runMenuItem,windowMenuItem,
            AnimMenuItem,helpMenuItem,aboutMenuItem;
    String[] sName;
    int w,h;
    Panel a;
    int x=0;

    myMorphingPanel95 p;

    /*
     * 17.在myMorphing95构造器中,
     * 添加菜单条,
     * 并为各个菜单项添加事件监听
     */
    public myMorphing95(){
        this.setLayout(bLayout);
        this.setTitle("Morphing图像变形");

        a =new bgPanel();
        a.setSize(650,600);
        a.setLayout(bLayout);
        this.add(a,BorderLayout.CENTER);

        MenuBar mbar = new MenuBar();
        Menu fileMenu = new Menu("文件",true);
        Menu editMenu = new Menu("编辑",true);
        Menu runMenu = new Menu("运行",true);
        Menu helpMenu = new Menu("帮助",true);
        fileMenu.add(loadMenuItem=new MenuItem("打开图像文件"));
        fileMenu.addSeparator();
        fileMenu.add(exitMenuItem=new MenuItem("退出"));
        editMenu.add(inMenuItem=new MenuItem("输入特征值"));
        editMenu.add(outMenuItem=new MenuItem("输出特征值"));
        runMenu.add(runMenuItem=new MenuItem("运行"));
        runMenu.add(AnimMenuItem=new MenuItem("运行动画"));
        helpMenu.add(helpMenuItem=new MenuItem("使用说明"));
        helpMenu.addSeparator();
        helpMenu.add(aboutMenuItem=new MenuItem("关于"));
        mbar.add(fileMenu);
        mbar.add(editMenu);
        mbar.add(runMenu);
        mbar.add(helpMenu);
        setMenuBar(mbar);
        loadMenuItem.addActionListener(this);
        exitMenuItem.addActionListener(this);
        inMenuItem.addActionListener(this);
        outMenuItem.addActionListener(this);
        runMenuItem.addActionListener(this);
        AnimMenuItem.addActionListener(this);
        helpMenuItem.addActionListener(this);
        /*
         * 当用户单击“关于”菜单时,运行aboutMenuItem_actionPerformed()方法
         */
        aboutMenuItem.addActionListener(new ActionListener(){
            public void actionPerformed(ActionEvent e){
                aboutMenuItem_actionPerformed(e);
            }
        });
        /*
         * 当用户单击关闭按钮时,退出系统
         */
        addWindowListener(new WindowAdapter(){
            public void windowClosing(WindowEvent e){
                System.exit(0);
            }
        });


    }
/*
 * 18.判断用户的菜单事件,如果事件为“打开图像文件”,
 * 则连续两次调用sLoad_actionPerformed()方法,
 * 并实例化myMorphing95Panel对象;
 * 如果事件为"退出,则退出系统;
 * 如果事件为"输入特征值",
 * 则调用p.in_actionPerformed()方法;
 * 事件为"输出特征值",
 * 则调用p.out_actionPerformed()方法,
 * 以此类推
 */
public void actionPerformed(ActionEvent e){
    if(e.getActionCommand().equals("打开图像文件")) {
        sName = new String[2];
        x=0;
        while(x<2){
            sName[x]=sLoad_actionPerformed(e);
            x++;
        }
    }
    if(x==2){
        if(a.getComponentCount()!=0)
            a.removeAll();
        p=new myMorphingPanel95(sName[0],sName[1]);
        p.setSize(650,600);
        a.add(p,BorderLayout.CENTER);
        p.repaint();
        repaint();
    }
    
    if(e.getActionCommand().equals("退出")){
        System.exit(0);
    }
    if(e.getActionCommand().equals("输入特征值")){
        p.in_actionPerformed(sName[0],sName[1]);
        p.repaint();
    }
    if(e.getActionCommand().equals("输出特征值")){
        p.out_actionPerformed(sName[0],sName[1]);
    }
    if(e.getActionCommand().equals("运行")){
        p.process_actionPerformed();
    }
    if(e.getActionCommand().equals("运行动画")){
        p.tt();
    }
    if(e.getActionCommand().equals("使用说明")){
        help zz = new help();
        zz.setModal(true);
        zz.setVisible(true);
    }
}
    /*
     * 19.定义aboutMenuItem_actionPerformed()方法,
     * 实例化Framel_AboutBox,显示一个“关于”窗口
     */
public void aboutMenuItem_actionPerformed(ActionEvent e){
    Framel_AboutBox dlg = new Framel_AboutBox(this);
    dlg.setModal(true);
    dlg.setVisible(true);
}
/*
 * 20.重写update()方法
 */
public void update(Graphics g){
    paint(g);
    super.paintComponents(g);
}
/*
 * 21.在main()方法实例化myMorphing95
 */
public static void main(String[] args){
    myMorphing95 f = new myMorphing95();
    f.setSize(650,600);
    f.setVisible(true);
}
/*
 * 22.定义sLoad_actiongPerformed()方法,实例化一个文件对话框,用于选择源图像和目标图像
 */
public String sLoad_actionPerformed(ActionEvent e){
    FileDialog sLoad = new FileDialog(this,"load");
    sLoad.setVisible(true);
    String sName = sLoad.getFile();
    return sName;
   }
}
/*
 * 23.定义help类,作为Jdialo类的子类,用于显示一个帮助框
 */
class help extends JDialog{
    String s1="使用说明: \r\n";
    JPanel ContentPane;

    public help(){
        ContentPane = (JPanel)this.getContentPane();
        TextArea helpArea = new TextArea(s1);
        helpArea.setColumns(60);
        String s2="1.装载源图像和目标图像,从菜单中选择:。。。。。";//使用帮助说明,略。
        helpArea.append(s2);
        ContentPane.add(helpArea);
        this.setSize(400,200);
    }
};
/*
 * 24.定义bgPanel类,用于在程序启动时显示一个背景图案
 */
class bgPanel extends Panel{
    Image bgim;

    public bgPanel(){
        MediaTracker tracker=new MediaTracker(this);
        bgim=Toolkit.getDefaultToolkit().getImage("bg.jpg");
        tracker.addImage(bgim,0);
        try{
            tracker.waitForID(0);
        }catch(InterruptedException e){e.printStackTrace();}
    }

    public void paint(Graphics g){
        g.drawImage(bgim,0,0,this);
    }
};
/*
 * 25.定义Framel_AboutBox()类,作为Jdialog类的子类,实现ActionListener接口
 */
class Framel_AboutBox extends JDialog implements ActionListener{
    JPanel panel1 = new JPanel();
    JPanel panel2 = new JPanel();
    JPanel insetsPanel1 = new JPanel();
    JPanel insetsPanel2 = new JPanel();
    JPanel insetsPanel3 = new JPanel();
    JButton button1 = new JButton();
    JLabel imageLabel = new JLabel();
    JLabel label1 = new JLabel();
    JLabel label2 = new JLabel();
    JLabel label3 = new JLabel();
    JLabel label4 = new JLabel();
    BorderLayout borderLayout1 = new BorderLayout();
    BorderLayout borderLayout2 = new BorderLayout();
    FlowLayout flowLayout1 = new FlowLayout();
    GridLayout gridLayout1 = new GridLayout();
    String product = "MorphMan-Image Morphing Software";
    String version = "1.0";
    String copyright = "Copyright  (c) 2003";
    String comments = "";
    public Framel_AboutBox(Frame parent){
        super(parent);
        enableEvents(AWTEvent.WINDOW_EVENT_MASK);
        try{
            jbInit();
        }
        catch(Exception e){
            e.printStackTrace();
        }
        pack();
    }
    private void jbInit() throws Exception{
        this.setTitle("About");
        setResizable(false);
        panel1.setLayout(borderLayout1);
        panel2.setLayout(borderLayout2);
        insetsPanel1.setLayout(flowLayout1);
        insetsPanel2.setLayout(flowLayout1);
        insetsPanel2.setBorder(BorderFactory.createEmptyBorder(10,10,10,10));
        gridLayout1.setRows(4);
        gridLayout1.setColumns(1);
        label1.setText(product);
        label2.setText(version);
        label3.setText(copyright);
        label4.setText(comments);
        insetsPanel3.setLayout(gridLayout1);
        insetsPanel3.setBorder(BorderFactory.createEmptyBorder(10,60,10,10));
        button1.setText("OK");
        button1.addActionListener(this);
        imageLabel.setIcon(new
                ImageIcon(Framel_AboutBox.class.getResource("ninja-weapon.gif")));
        insetsPanel2.add(insetsPanel2,BorderLayout.WEST);
        this.getContentPane().add(panel1,null);
        insetsPanel3.add(label1,null);
        insetsPanel3.add(label2,null);
        insetsPanel3.add(label3,null);
        insetsPanel3.add(label4,null);
        panel2.add(insetsPanel3,BorderLayout.CENTER);
        insetsPanel1.add(button1,null);
        panel1.add(insetsPanel1,BorderLayout.SOUTH);
        panel1.add(panel2,BorderLayout.NORTH);
    }
    protected void processWindowEvent(WindowEvent e){
        if(e.getID() == WindowEvent.WINDOW_CLOSING){
            cancel();
        }
        super.processWindowEvent(e);
    }
    void cancel(){
        dispose();
    }
    public void actionPerformed(ActionEvent e){
        if(e.getSource() == button1){
            cancel();
        }
    }

}



加载中
0
阿信sxq
阿信sxq
不是说数组下标越界吗,你看看它说的那里是不是真的越界呢
阿信sxq
阿信sxq
回复 @熵增- : 很奇怪,我运行起来没有出现你说的那个异常,但是也是不出结果
熵增-
熵增-
它指了很多行代码,在图里可以看到,但是其中有很多行里面并没有运用数组...
0
贝克街的亡灵sf
贝克街的亡灵sf
哪里报错没有指明吗。数组下标越界是会指向哪行的啊。。
熵增-
熵增-
它指了很多行代码,但是其中有很多里面并没有运用数组...
0
MZHS
MZHS

一行一行打断点是不是找的很慢,报错信息又找不到自己的代码?这招一般人我不告诉他
熵增-
熵增-
不好意思,我不太懂你的意思0.0
返回顶部
顶部