1 /* Copyright (C) 2005-2011 Fabio Riccardi */ 2 3 package com.lightcrafts.model.ImageEditor; 4 5 import com.lightcrafts.model.*; 6 import com.lightcrafts.jai.utils.*; 7 import com.lightcrafts.jai.JAIContext; 8 9 import com.lightcrafts.mediax.jai.*; 10 import com.lightcrafts.mediax.jai.operator.ConvolveDescriptor; 11 import com.lightcrafts.ui.LightZoneSkin; 12 13 import java.awt.*; 14 import java.awt.event.ComponentAdapter; 15 import java.awt.event.ComponentEvent; 16 import java.awt.image.*; 17 import java.awt.image.renderable.ParameterBlock; 18 import java.awt.geom.AffineTransform; 19 import java.lang.ref.SoftReference; 20 21 public class PassThroughPreview 22 extends Preview implements PaintListener 23 { 24 private ImageEditorEngine engine; 25 PassThroughPreview(ImageEditorEngine engine)26 PassThroughPreview(ImageEditorEngine engine) { 27 this.engine = engine; 28 addComponentListener( 29 new ComponentAdapter() { 30 public void componentResized(ComponentEvent event) { 31 if (isShowing()) { 32 PassThroughPreview.this.engine.update(null, false); 33 } 34 } 35 } 36 ); 37 } 38 39 @Override getName()40 public String getName() { 41 return "Pass Through"; 42 } 43 44 @Override setDropper(Point p)45 public void setDropper(Point p) { 46 } 47 48 @Override addNotify()49 public void addNotify() { 50 // This method gets called when this Preview is added. 51 engine.update(null, false); 52 super.addNotify(); 53 } 54 55 @Override removeNotify()56 public void removeNotify() { 57 // This method gets called when this Preview is removed. 58 super.removeNotify(); 59 } 60 61 @Override setRegion(Region region)62 public void setRegion(Region region) { 63 // Fabio: only draw yellow inside the region? 64 } 65 66 private SoftReference<PlanarImage> currentImage = new SoftReference<PlanarImage>(null); 67 private Rectangle visibleRect = null; 68 private BufferedImage preview = null; 69 70 @Override setSelected(Boolean selected)71 public void setSelected(Boolean selected) { 72 if (!selected) { 73 preview = null; 74 currentImage = new SoftReference<PlanarImage>(null); 75 } 76 } 77 78 @Override paintComponent(Graphics graphics)79 protected void paintComponent(Graphics graphics) { 80 // Fill in the background: 81 Graphics2D g = (Graphics2D) graphics; 82 Shape clip = g.getClip(); 83 g.setColor(LightZoneSkin.Colors.NeutralGray); 84 g.fill(clip); 85 86 if (preview == null) { 87 PlanarImage image = currentImage.get(); 88 if (image == null) { 89 engine.update(null, false); 90 } 91 else if (visibleRect != null && getHeight() > 1 && getWidth() > 1) { 92 preview = cropScaleGrayscale(visibleRect, image); 93 } 94 } 95 if (preview != null) { 96 int dx, dy; 97 AffineTransform transform = new AffineTransform(); 98 if (getSize().width > preview.getWidth()) 99 dx = (getSize().width - preview.getWidth()) / 2; 100 else 101 dx = 0; 102 if (getSize().height > preview.getHeight()) 103 dy = (getSize().height - preview.getHeight()) / 2; 104 else 105 dy = 0; 106 transform.setToTranslation(dx, dy); 107 try { 108 g.drawRenderedImage(preview, transform); 109 } 110 catch (Exception e) { 111 e.printStackTrace(); 112 } 113 } 114 } 115 cropScaleGrayscale( Rectangle visibleRect, RenderedImage image )116 private BufferedImage cropScaleGrayscale( 117 Rectangle visibleRect, RenderedImage image 118 ) { 119 int minX = image.getMinX(); 120 int minY = image.getMinY(); 121 int width = image.getWidth(); 122 int height = image.getHeight(); 123 124 Rectangle bounds = new Rectangle(minX, minY, width, height); 125 126 visibleRect = bounds.intersection(visibleRect); 127 128 if (bounds.contains(visibleRect)) { 129 ParameterBlock pb = new ParameterBlock(); 130 pb.addSource(image); 131 pb.add((float) visibleRect.x); 132 pb.add((float) visibleRect.y); 133 pb.add((float) visibleRect.width); 134 pb.add((float) visibleRect.height); 135 image = JAI.create("Crop", pb, JAIContext.noCacheHint); 136 } 137 Dimension previewSize = getSize(); 138 139 if ((visibleRect.width > previewSize.width) || 140 (visibleRect.height > previewSize.height) 141 ) { 142 float scale = Math.min( 143 previewSize.width / (float) visibleRect.width, 144 previewSize.height / (float) visibleRect.height); 145 146 image = ConvolveDescriptor.create( 147 image, Functions.getGaussKernel(.25 / scale), null 148 ); 149 ParameterBlock pb = new ParameterBlock(); 150 pb.addSource(image); 151 pb.add(scale); 152 pb.add(scale); 153 image = JAI.create("Scale", pb, JAIContext.noCacheHint); 154 } 155 image = 156 Functions.toColorSpace(image, JAIContext.systemColorSpace, null); 157 158 if (image.getSampleModel().getDataType() == DataBuffer.TYPE_USHORT) { 159 image = Functions.fromUShortToByte(image, null); 160 } 161 return Functions.toFastBufferedImage(image); 162 } 163 164 @Override paintDone( PlanarImage image, Rectangle visibleRect, boolean synchronous, long time )165 public void paintDone( 166 PlanarImage image, 167 Rectangle visibleRect, 168 boolean synchronous, 169 long time 170 ) { 171 if (image == null) 172 return; 173 174 Dimension previewDimension = getSize(); 175 if ((previewDimension.getHeight() > 1) && 176 (previewDimension.getWidth() > 1) 177 ) { 178 this.visibleRect = visibleRect; 179 currentImage = new SoftReference<PlanarImage>(image); 180 preview = null; 181 repaint(); 182 } 183 } 184 } 185