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; } } } } } |