java 标准MVC下图像处理器 1(框架)

来源:互联网 发布:淘宝代销产品怎么上架 编辑:程序博客网 时间:2024/05/14 20:39

MVC 已经听的烂熟了,但是能熟练使用的人不多。这个图像过滤器框架是我用来练习的。

源代码下载:http://soulnew.googlepages.com/JPhoto.rar

简单做了4个滤镜,详细的算法介绍,在下一篇《标准MVC图像处理器 2(滤镜)》

 先是视图(view)

用来监听模型(model)变化。一旦获得模型广播出来的事件,

 
package com.soulnew.Grapha.View;

import com.soulnew.Grapha.Model.JPhotoModel;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Image;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import javax.swing.ImageIcon;
import javax.swing.JPanel;


/**
 *
 * @author soulnew@gmail.com
 * @ blog:     http://souljava.blog.163.com
 */
public class JPhotoView extends JPanel implements PropertyChangeListener{
    JPhotoModel model;
    Image image;
    int w,h;


    public JPhotoView(){
        super();
       
    }
    public JPhotoView(String imagename){
        super();       
        image=(new ImageIcon(imagename)).getImage() ;
        h=image.getHeight(null);
        w=image.getWidth(null);
        setPreferredSize(new Dimension(w,h));
//        System.out.print("/nw and h:"+w+","+h);
    }
   
    public void propertyChange(PropertyChangeEvent evt) {
        image= (Image)evt.getNewValue();
        h=image.getHeight(null);
        w=image.getWidth(null);
        this.repaint();
       
    }
    public void paintComponent(Graphics g){
        super.paintComponent(g);
        g.drawImage(image, 0, 0, null);
        setPreferredSize(new Dimension(w,h));
      }
}

 

 

 

模型(JPhotoModel),由控制器调用它的setValue(),然后计算出过滤后的图像,作为参数广播给监听自己的 视图

package com.soulnew.Grapha.Model;

import com.soulnew.Grapha.Model.AbstractPixelModel;
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
import java.util.LinkedList;

/**
 *
 * @author soulnew@gmail.com
 * @ blog:     http://souljava.blog.163.com
 */
public class JPhotoModel {
    PropertyChangeSupport changeSupport;
    LinkedList<AbstractPixelModel> modelList=new LinkedList<AbstractPixelModel>();
   // int modelindex;
    public JPhotoModel() {
        changeSupport =new PropertyChangeSupport(this);
       
    }
   
    public void setValue(int modelindex,int[] pixels,int w,int h){ 
//        this. modelindex= modelindex;
        AbstractPixelModel pixelmodel=(AbstractPixelModel) modelList.get(modelindex);
        pixelmodel.setPixels(pixels, w, h);       
        changeSupport.firePropertyChange("propertyName",true,pixelmodel.getPixels());
    }

    public void addPropertyChangeListener(PropertyChangeListener listener){
        changeSupport.addPropertyChangeListener(listener);
    }
   
    public void addPixelModel(int index,AbstractPixelModel a){
         modelList.add(index,a);
    }
    public void getPixel(){
       
    }
}

控制器的主要代码:

在控制器(contrl)中, 设置模型和视图的关联

        jview=new JPhotoView(imagefile);
        jmodel=new JPhotoModel();
        jmodel.addPropertyChangeListener(jview);
        jmodel.addPixelModel(darkPixelModel,new DarkPixelModel());
        jmodel.addPixelModel(canvasPixelModel,new CanvasPixelModel());
        jmodel.addPixelModel(woodcutPixelModel,new WoodCutPixelModel());
        jmodel.addPixelModel(embossmentPixelModel,new EmbossmentPixelModel());

 控制器触发模型以触发视图改变:

 jmodel.setValue(woodcutPixelModel,pixels,w,h);

滤镜的基础模型: 

原来想作成interface,结果发现有几个子类必须有的方法,内容有重复,就改成了abstract

 
package com.soulnew.Grapha.Model;

import java.awt.Image;
import java.awt.image.MemoryImageSource;
import javax.swing.JFrame;

/**
 *
 * @author soulnew@gmail.com
 * @ blog:     http://souljava.blog.163.com
 */

public abstract class AbstractPixelModel {
    int w,h;
    int[] pixels;
    public Image getPixels(){
        JFrame j=new JFrame();
        Image modImg = j.createImage(
                new MemoryImageSource(w,h,pixels,0,w));
        return modImg;
    }
    public void setPixels(int[] pixels,int w,int h){
        this.pixels=pixels;
        this.w=w;
        this.h=h;
        dopiexl(pixels,w,h);
    }
    public void dopiexl(int[] pixels,int w,int h){
       
    }
   
}

 

每个滤镜只要重写AbstractPixelModel的 一个方法:

public void dopiexl(int[] pixels,int w,int h)就可以了

下篇有详细的滤镜介绍

一个木刻效果的滤镜:

 

 
package com.soulnew.Grapha.Model;
/**
 *
 * @author soulnew@gmail.com
 * @ blog:     http://souljava.blog.163.com
 */
public class WoodCutPixelModel extends AbstractPixelModel {
   
    public WoodCutPixelModel() {
    }
   
    public void dopiexl(int[] pixels,int w,int h){
        //int[] save=pixels;
        for(int i=0;i<h;i++){
            for(int j=0;j<w;j++){
                int pixel=pixels[i*w+j];
                int red   = (pixel >> 16) & 0xff;
                int green = (pixel >>  8) & 0xff;
                int blue  = (pixel     ) & 0xff;
                if(((red+green+blue)/3)>190){
                    pixels[i*w+j]=0xffffffff;
                }else if(((red+green+blue)/3)>85){
                    pixels[i*w+j]=0x88888888;
                }else{
                    pixels[i*w+j]=0;
                }
                   
            }
        }
    }
}