Changeset 60:88826a8c5728
- Timestamp:
- 04/13/08 09:21:03 (4 years ago)
- Tags:
- tip
- Location:
- src
- Files:
-
- 1 added
- 11 modified
-
main/pcapp/org/freecine/sane/FixedPointNumber.java (modified) (1 diff)
-
main/pcapp/org/freecine/sane/SaneDevice.java (modified) (5 diffs)
-
main/pcapp/org/freecine/swingui/PreviewPane.form (modified) (1 diff)
-
main/pcapp/org/freecine/swingui/PreviewPane.java (modified) (8 diffs)
-
main/pcapp/org/freecine/swingui/ScanPreviewDlg.form (modified) (3 diffs)
-
main/pcapp/org/freecine/swingui/ScanPreviewDlg.java (modified) (9 diffs)
-
main/pcapp/org/freecine/swingui/ScanPreviewTask.java (modified) (6 diffs)
-
main/pcapp/org/freecine/swingui/ScanProgressDlg.java (modified) (5 diffs)
-
main/pcapp/org/freecine/swingui/ScanTask.java (modified) (7 diffs)
-
main/pcapp/org/freecine/swingui/resources/ScanPreviewDlg.properties (modified) (1 diff)
-
main/pcapp/org/freecine/swingui/resources/ScanTask.properties (modified) (1 diff)
-
test/pcapp/org/freecine/sane/TestFixedPointNumber.java (added)
Legend:
- Unmodified
- Added
- Removed
-
src/main/pcapp/org/freecine/sane/FixedPointNumber.java
r50 r60 27 27 28 28 /** 29 * 30 * @author harri 29 Fixed point number used when setting parameters for Sane. 30 31 Sane uses 32 bit fixed point number (with 16 bit integer, 16 bit fractional 32 part for many parameters. This class provides conversions and basic arithmetic 33 operations for those. 34 31 35 */ 32 public class FixedPointNumber { 36 public class FixedPointNumber implements Comparable { 37 38 final static int SANE_FIXED_SCALE_SHIFT = 16; 39 40 /** 41 Value of the number, shifted left SANE_FIXED_SCALE_SHIFT bits 42 */ 33 43 private int val; 44 45 /** 46 Creates a new fixed point number from the SANE internal representation of it 47 @param fpval 48 */ 34 49 public FixedPointNumber( int fpval ) { 35 50 val = fpval; 36 51 } 37 52 53 /** 54 Get the representation that Sane uses for this number 55 @return 56 */ 38 57 public int getVal() { 39 58 return val; 40 59 } 41 60 61 /** 62 Test for equality 63 @param o The object to test with 64 @return true if this object and o are equal, false otherwise 65 */ 66 @Override 67 public boolean equals( Object o ) { 68 if ( o == this ) { 69 return true; 70 } 71 if ( !(o instanceof FixedPointNumber) ) { 72 return false; 73 } 74 FixedPointNumber f = (FixedPointNumber) o; 75 return f.val == val; 76 } 77 78 /** 79 Calculate hash code for this object 80 @return 81 */ 82 @Override 83 public int hashCode() { 84 int hash = 7; 85 hash = 67 * hash + this.val; 86 return hash; 87 } 88 89 /** 90 Compare with another FixedPointNumber 91 @param o 92 @return 93 */ 94 public int compareTo( Object o ) { 95 FixedPointNumber f = (FixedPointNumber) o; 96 if ( val > f.val ) { 97 return 1; 98 } 99 if ( val < f.val ) { 100 return -1; 101 } 102 return 0; 103 } 104 105 /** 106 Add two fixed point numbers 107 @param f The number to add to this. 108 @return FixedPointNumber with value this+f 109 */ 110 public FixedPointNumber add( FixedPointNumber f ) { 111 return new FixedPointNumber( this.val + f.val ); 112 } 113 114 /** 115 Subtract two fixed point numbers 116 @param f The number to subtract from this. 117 @return FixedPointNumber with value this-f 118 */ 119 public FixedPointNumber subtract( FixedPointNumber f ) { 120 return new FixedPointNumber( this.val - f.val ); 121 } 122 123 /** 124 Convert this fixed point nubmer to double 125 @return double with value that is as close as possible to value of this. 126 */ 127 public double toDouble() { 128 return (double)val / (double)( 1 << SANE_FIXED_SCALE_SHIFT ); 129 } 130 131 /** 132 Convert the number to string 133 @return 134 */ 135 @Override 136 public String toString() { 137 int intPart = val >> SANE_FIXED_SCALE_SHIFT; 138 int fracPart = val & ( (1 << SANE_FIXED_SCALE_SHIFT) -1); 139 String str = "" + intPart; 140 if ( fracPart != 0 ) { 141 str += " " + fracPart + "/" + (1 << SANE_FIXED_SCALE_SHIFT ); 142 } 143 return str; 144 } 145 146 /** 147 Create a new fixed point number whose value is close to given double 148 precision number 149 @param v 150 @return 151 */ 152 public static FixedPointNumber valueOf( double v ) { 153 double v2 = v * (double)(1<<SANE_FIXED_SCALE_SHIFT); 154 return new FixedPointNumber( (int)v2 ); 155 } 42 156 } -
src/main/pcapp/org/freecine/sane/SaneDevice.java
r59 r60 101 101 if ( desc.getType() == OptionType.SANE_TYPE_STRING ) { 102 102 if ( desc.size >= value.length() ) { 103 int status = sane.sane_control_option(deviceHandle, id, 1, value, null ); 103 IntByReference info = new IntByReference(); 104 int status = sane.sane_control_option(deviceHandle, id, 1, value, info ); 104 105 if ( status != 0 ) { 105 106 throw new SaneException( "Error setting option " + option + " to " + value ); 107 } 108 // Check if options need to be reloaded 109 if ( ( info.getValue() & 2 ) != 0 ) { 110 initOptions(); 106 111 } 107 112 } else { … … 126 131 if ( desc.getType() == OptionType.SANE_TYPE_INT ) { 127 132 if ( desc.size == value.length * 4 ) { 128 int status = sane.sane_control_option(deviceHandle, id, 1, value, null ); 133 IntByReference info = new IntByReference(); 134 int status = sane.sane_control_option(deviceHandle, id, 1, value, info ); 129 135 if ( status != 0 ) { 130 136 throw new SaneException( "Error setting option " + option ); 137 } 138 // Check if options need to be reloaded 139 if ( ( info.getValue() & 2 ) != 0 ) { 140 initOptions(); 131 141 } 132 142 } else { … … 147 157 } 148 158 149 public voidsetOption( String option, FixedPointNumber[] value ) throws SaneException {159 public FixedPointNumber[] setOption( String option, FixedPointNumber[] value ) throws SaneException { 150 160 if ( optionIds == null ) { 151 161 initOptions(); 152 162 } 163 FixedPointNumber[] newValue = value; 153 164 int id = -1; 154 165 if ( optionIds.containsKey(option ) ) { … … 161 172 } 162 173 if ( desc.size == value.length * 4 ) { 163 int status = sane.sane_control_option(deviceHandle, id, 1, v, null ); 174 IntByReference info = new IntByReference(); 175 int status = sane.sane_control_option(deviceHandle, id, 1, v, info ); 164 176 if ( status != 0 ) { 165 177 throw new SaneException( "Error setting option " + option ); 178 } 179 // Check if options need to be reloaded 180 if ( ( info.getValue() & 2 ) != 0 ) { 181 initOptions(); 182 } 183 if ( ( info.getValue() & 1 ) != 0 ) { 184 System.err.println( "Value modified :" ); 185 newValue = new FixedPointNumber[value.length]; 186 for ( int n = 0 ; n < v.length ; n++ ) { 187 newValue[n] = new FixedPointNumber( v[n] ); 188 } 166 189 } 167 190 } else { … … 174 197 throw new SaneException( "No option named " + option ); 175 198 } 176 177 } 178 179 public voidsetOption( String option, FixedPointNumber value ) throws SaneException {199 return newValue; 200 } 201 202 public FixedPointNumber setOption( String option, FixedPointNumber value ) throws SaneException { 180 203 FixedPointNumber[] a = {value}; 181 setOption( option, a );204 return setOption( option, a )[0]; 182 205 } 206 183 207 184 208 public void startScan() throws SaneException { -
src/main/pcapp/org/freecine/swingui/PreviewPane.form
r59 r60 9 9 <EventHandler event="mouseReleased" listener="java.awt.event.MouseListener" parameters="java.awt.event.MouseEvent" handler="formMouseReleased"/> 10 10 <EventHandler event="mouseDragged" listener="java.awt.event.MouseMotionListener" parameters="java.awt.event.MouseEvent" handler="formMouseDragged"/> 11 <EventHandler event="mouseMoved" listener="java.awt.event.MouseMotionListener" parameters="java.awt.event.MouseEvent" handler="formMouseMoved"/> 11 12 </Events> 12 13 <AuxValues> -
src/main/pcapp/org/freecine/swingui/PreviewPane.java
r59 r60 56 56 BufferedImage scaledImage; 57 57 58 int magnWidth = 100; 59 58 60 public void setPreviewImage( BufferedImage img ) { 59 61 BufferedImage oldPreview = previewImage; … … 121 123 } 122 124 ((Graphics2D) g).drawRenderedImage( scaledImage, null ); 123 } 124 125 if ( selection != null ) { 125 126 // Draw the magnification window 127 int imageX = (int)((double)lastMouseX / scale) - magnWidth / 2; 128 int imageY = (int)((double)lastMouseY / scale) - magnWidth / 2; 129 130 imageX = Math.max( 0, imageX ); 131 imageX = Math.min( previewImage.getWidth()-magnWidth, imageX ); 132 imageY = Math.max( 0, imageY ); 133 imageY = Math.min( previewImage.getHeight() - magnWidth, imageY ); 134 BufferedImage magnImage = previewImage.getSubimage( imageX, imageY, magnWidth, magnWidth ); 135 ((Graphics2D) g).drawImage( magnImage, null, 0, getHeight() - magnWidth ); 136 137 } 138 139 if ( selection != null && scaledImage != null ) { 126 140 // Calculate device space coordinates for the selection rectangle 127 double w = getWidth();128 double h = getHeight();141 double w = scaledImage.getWidth(); 142 double h = scaledImage.getHeight(); 129 143 double tlx = w * (( selection.getMinX()-previewArea.getMinX() ) / previewArea.getWidth()); 130 144 double tly = h * (( selection.getMinY()-previewArea.getMinY() ) / previewArea.getHeight()); … … 147 161 } 148 162 149 /** 150 Calculate scaledIamge from previewImage so that it fits in the control 163 double scale = 1.0; 164 165 /** 166 Calculate scaledIamge from previewImage so that it fits in the control. The 167 scale of scaledImage is stored in scale member. 151 168 */ 152 169 private void scaleImage() { … … 158 175 double xscale = (double)compWidth / (double) iw; 159 176 double yscale = (double)compHeight / (double) ih; 160 doublescale = Math.min( xscale, yscale );177 scale = Math.min( xscale, yscale ); 161 178 AffineTransform xform = AffineTransform.getScaleInstance( scale, scale ); 162 179 AffineTransformOp xformOp = new AffineTransformOp( xform, null ); … … 186 203 public void mouseDragged(java.awt.event.MouseEvent evt) { 187 204 formMouseDragged(evt); 205 } 206 public void mouseMoved(java.awt.event.MouseEvent evt) { 207 formMouseMoved(evt); 188 208 } 189 209 }); … … 217 237 private void formMouseDragged(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_formMouseDragged 218 238 log.entering("PreviewPane", "formMouseDragged"); 239 240 lastMouseX = evt.getX(); 241 lastMouseY = evt.getY(); 242 243 if ( scaledImage == null ) { 244 return; 245 } 219 246 Point2D p1 = screenToDev( dragStartX, dragStartY ); 220 247 Point2D p2 = screenToDev( evt.getX(), evt.getY() ); … … 227 254 private void formMouseReleased(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_formMouseReleased 228 255 log.entering( "PreviewPane", "formMouseReleased" ); 256 if ( scaledImage == null ) { 257 return; 258 } 229 259 Point2D p1 = screenToDev( dragStartX, dragStartY ); 230 260 Point2D p2 = screenToDev( evt.getX(), evt.getY() ); … … 232 262 s.add( p2 ); 233 263 setSelection( s ); 264 log.severe( "new area " + s ); 234 265 log.exiting("PreviewPane", "formMouseDragged"); 235 266 }//GEN-LAST:event_formMouseReleased 236 237 /** 238 Convert position from screen coordinates to scanner device coordinates 267 268 int lastMouseX = 0; 269 int lastMouseY = 0; 270 271 private void formMouseMoved(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_formMouseMoved 272 lastMouseX = evt.getX(); 273 lastMouseY = evt.getY(); 274 repaint(); 275 }//GEN-LAST:event_formMouseMoved 276 277 /** 278 Convert position from screen coordinates to scanner device coordinates. 279 To call this function, the scaledImage must exist as it defines the mapping 280 screen space coordinate system 239 281 @param x 240 282 @param y 241 283 @return 242 284 */ 243 Point2D screenToDev( int x, int y ) {244 double w = getWidth();245 double h = getHeight();285 private Point2D screenToDev( int x, int y ) { 286 double w = scaledImage.getWidth(); 287 double h = scaledImage.getHeight(); 246 288 double devx = previewArea.getMinX() + previewArea.getWidth() * (x/w); 247 289 double devy = previewArea.getMinY() + previewArea.getHeight() * (y/h); -
src/main/pcapp/org/freecine/swingui/ScanPreviewDlg.form
r59 r60 26 26 <EmptySpace max="-2" attributes="0"/> 27 27 <Component id="previewPane" min="-2" max="-2" attributes="0"/> 28 <EmptySpace pref="75" max="32767" attributes="0"/> 29 <Component id="startPreviewScanBtn" min="-2" max="-2" attributes="0"/> 28 <EmptySpace max="32767" attributes="0"/> 29 <Group type="103" groupAlignment="1" attributes="0"> 30 <Component id="startPreviewScanBtn" min="-2" max="-2" attributes="0"/> 31 <Component id="okBtn" alignment="1" min="-2" max="-2" attributes="0"/> 32 </Group> 30 33 <EmptySpace max="-2" attributes="0"/> 31 34 </Group> … … 37 40 <EmptySpace max="-2" attributes="0"/> 38 41 <Group type="103" groupAlignment="0" attributes="0"> 39 <Component id="startPreviewScanBtn" alignment="0" min="-2" max="-2" attributes="0"/> 42 <Group type="102" alignment="0" attributes="0"> 43 <Component id="startPreviewScanBtn" min="-2" max="-2" attributes="0"/> 44 <EmptySpace max="-2" attributes="0"/> 45 <Component id="okBtn" min="-2" max="-2" attributes="0"/> 46 </Group> 40 47 <Component id="previewPane" alignment="0" max="32767" attributes="0"/> 41 48 </Group> … … 80 87 </Properties> 81 88 </Component> 89 <Component class="javax.swing.JButton" name="okBtn"> 90 <Properties> 91 <Property name="action" type="javax.swing.Action" editor="org.netbeans.modules.swingapp.ActionEditor"> 92 <action class="org.freecine.swingui.ScanPreviewDlg" id="ok" methodName="ok"/> 93 </Property> 94 <Property name="name" type="java.lang.String" value="okBtn" noResource="true"/> 95 </Properties> 96 </Component> 82 97 </SubComponents> 83 98 </Form> -
src/main/pcapp/org/freecine/swingui/ScanPreviewDlg.java
r59 r60 26 26 package org.freecine.swingui; 27 27 28 import java.awt.geom.Rectangle2D; 28 29 import java.awt.image.BufferedImage; 29 30 import java.util.concurrent.ExecutionException; … … 56 57 initComponents(); 57 58 } 58 59 59 /** 60 60 The scanner used … … 79 79 firePropertyChange( "scanner", oldScanner, s ); 80 80 } 81 82 /** 83 Scan area 84 */ 85 Rectangle2D scanArea; 86 87 /** 88 Get the currently set scan area. 89 @return Rectangle describing currently selected scan area, in device 90 coordinate units. The units are the same used by Sane back end for this type 91 of scanner (e.g. millimeters, not pixels) 92 */ 93 public Rectangle2D getScanArea() { 94 return scanArea; 95 } 96 97 /** 98 Set the scan area displayed in the dialog. 99 @param newArea New area, in device coordinate units (see getScanArea() for 100 more information. 101 */ 102 public void setScanArea( Rectangle2D newArea ) { 103 Rectangle2D oldVal = scanArea; 104 scanArea = newArea; 105 ((PreviewPane)previewPane).setSelection( newArea ); 106 firePropertyChange( "scanArea", oldVal, newArea ); 107 } 108 81 109 82 110 /** This method is called from within the constructor to … … 90 118 previewPane = new PreviewPane(); 91 119 startPreviewScanBtn = new javax.swing.JButton(); 120 okBtn = new javax.swing.JButton(); 92 121 93 122 setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); … … 111 140 startPreviewScanBtn.setAction(actionMap.get("scanPreviewImage")); // NOI18N 112 141 startPreviewScanBtn.setName("startPreviewScanBtn"); // NOI18N 142 143 okBtn.setAction(actionMap.get("ok")); // NOI18N 144 okBtn.setName("okBtn"); // NOI18N 113 145 114 146 javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane()); … … 119 151 .addContainerGap() 120 152 .addComponent(previewPane, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) 121 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 75, Short.MAX_VALUE) 122 .addComponent(startPreviewScanBtn) 153 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) 154 .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) 155 .addComponent(startPreviewScanBtn) 156 .addComponent(okBtn)) 123 157 .addContainerGap()) 124 158 ); … … 128 162 .addContainerGap() 129 163 .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) 130 .addComponent(startPreviewScanBtn) 164 .addGroup(layout.createSequentialGroup() 165 .addComponent(startPreviewScanBtn) 166 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) 167 .addComponent(okBtn)) 131 168 .addComponent(previewPane, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) 132 169 .addContainerGap()) … … 168 205 try { 169 206 ((PreviewPane) previewPane).setPreviewImage( t.get() ); 207 208 ((PreviewPane) previewPane).setPreviewArea( t.getPreviewArea() ); 170 209 } catch ( InterruptedException ex ) { 171 210 log.log( Level.SEVERE, null, ex ); … … 179 218 } 180 219 220 /** 221 The OK button was pressed 222 */ 223 @Action 224 public void ok() { 225 Rectangle2D oldArea = scanArea; 226 scanArea = ((PreviewPane)previewPane).getSelection(); 227 setVisible( false ); 228 firePropertyChange( "scanArea", oldArea, scanArea ); 229 } 230 181 231 182 232 // Variables declaration - do not modify//GEN-BEGIN:variables 233 private javax.swing.JButton okBtn; 183 234 private javax.swing.JPanel previewPane; 184 235 private javax.swing.JButton startPreviewScanBtn; -
src/main/pcapp/org/freecine/swingui/ScanPreviewTask.java
r59 r60 27 27 28 28 import java.awt.Point; 29 import java.awt.Rectangle; 30 import java.awt.geom.Rectangle2D; 29 31 import java.awt.image.BufferedImage; 30 32 import java.awt.image.ColorModel; … … 57 59 private int TILE_WIDTH; 58 60 61 /** 62 Create a new preview task 63 @param app Application this task is associated with 64 @param dev ScanDevice to use 65 */ 59 66 public ScanPreviewTask( Application app, SaneDevice dev ) { 60 67 super( app ); … … 62 69 log.setLevel(Level.FINE); 63 70 } 64 71 72 /** 73 Area of the preview scan, in device coordinates. 74 */ 75 Rectangle2D previewArea = null; 76 77 /** 78 Get the area of preview scan 79 @return Preview area, in device coordinates. 80 */ 81 public Rectangle2D getPreviewArea() { 82 return previewArea; 83 } 84 85 /** 86 Do the actual scanning in background thread. 87 @return The scanned preview image. 88 @throws java.lang.Exception 89 */ 65 90 @Override 66 91 protected BufferedImage doInBackground() throws Exception { … … 78 103 dev.setOption( "mode", "Color" ); 79 104 dev.setOption( "depth", 16 ); 80 dev.setOption( "resolution", 100 );105 dev.setOption( "resolution", 200 ); 81 106 dev.setOption( "source", "Transparency Unit" ); 82 107 83 108 // Find out the maximum scanning area 84 int minX = -1;85 int maxX = -1;86 int minY = -1;87 int maxY = -1;109 FixedPointNumber minX = null; 110 FixedPointNumber maxX = null; 111 FixedPointNumber minY = null; 112 FixedPointNumber maxY = null; 88 113 SaneOptionDescriptor xdesc = dev.getOptionDesc( "tl-x" ); 89 114 switch ( xdesc.getConstraintType() ) { 90 115 case SANE_CONSTRAINT_RANGE: 91 116 SaneRange r = (SaneRange) xdesc.getConstraints(); 92 minX = r.min;93 maxX = r.max;117 minX = new FixedPointNumber( r.min ); 118 maxX = new FixedPointNumber( r.max ); 94 119 break; 95 120 case SANE_CONSTRAINT_WORD_LIST: 96 121 int[] values = (int[]) xdesc.getConstraints(); 97 minX = values[0];98 maxX = values[values.length-1];122 minX = new FixedPointNumber( values[0] ); 123 maxX = new FixedPointNumber( values[values.length-1] ); 99 124 break; 100 125 default: … … 105 130 case SANE_CONSTRAINT_RANGE: 106 131 SaneRange r = (SaneRange) ydesc.getConstraints(); 107 minY = r.min;108 maxY = r.max;132 minY = new FixedPointNumber( r.min ); 133 maxY = new FixedPointNumber( r.max ); 109 134 break; 110 135 case SANE_CONSTRAINT_WORD_LIST: 111 136 int[] values = (int[]) ydesc.getConstraints(); 112 minY = values[0];113 maxY = values[values.length-1];137 minY = new FixedPointNumber( values[0] ); 138 maxY = new FixedPointNumber( values[values.length-1] ); 114 139 break; 115 140 default: 116 141 throw new SaneException( "Cannod determinen scan glass area" ); 117 142 } 118 dev.setOption( "tl-x", new FixedPointNumber( minX ) ); 119 dev.setOption( "tl-y", new FixedPointNumber( minY ) ); 120 dev.setOption( "br-x", new FixedPointNumber( maxX ) ); 121 dev.setOption( "br-y", new FixedPointNumber( maxY ) ); 122 143 // if ( maxX.toDouble() > 8 * 25.4 ) { 144 // maxX = FixedPointNumber.valueOf( 8 * 25.4 ); 145 // } 146 // if ( maxY.toDouble() > 10 * 25.4 ) { 147 // maxY = FixedPointNumber.valueOf( 10 * 25.4 ); 148 // } 149 minX = dev.setOption( "tl-x", minX ); 150 minY = dev.setOption( "tl-y", minY ); 151 maxX = dev.setOption( "br-x", maxX ); 152 maxY = dev.setOption( "br-y", maxY ); 153 previewArea = new Rectangle2D.Double( minX.toDouble(), minY.toDouble(), 154 maxX.subtract(minX).toDouble(), maxY.subtract(minY).toDouble() ); 155 156 ScanParameter param = dev.getScanParameter(); 157 System.out.println( "Scan parameters: " + param.getPixelsPerLine() + " x " + param.getLines() ); 158 123 159 // Set gamma correction 124 160 dev.setOption( "gamma-correction", "User defined" ); … … 177 213 } 178 214 215 dev.close(); 179 216 return image; 180 217 -
src/main/pcapp/org/freecine/swingui/ScanProgressDlg.java
r59 r60 36 36 import org.freecine.sane.SaneException; 37 37 import java.awt.Graphics; 38 import java.awt.geom.Rectangle2D; 38 39 import java.beans.PropertyChangeEvent; 39 40 import java.beans.PropertyChangeListener; … … 247 248 248 249 } 249 scanTask = new ScanTask( dev, filmMover, null, prj );250 scanTask = new ScanTask( dev, filmMover, scanArea, prj ); 250 251 scanTask.addPropertyChangeListener( new PropertyChangeListener() { 251 252 … … 350 351 */ 351 352 public boolean isFilmMoverReady() { 352 return filmMover != null; 353 // return filmMover != null; 354 return true; 353 355 } 354 356 … … 372 374 } 373 375 376 Rectangle2D scanArea = null; 377 374 378 /** 375 379 Show the scan preview dialog 376 380 */ 377 @Action 381 @Action ( block=Task.BlockingScope.ACTION ) 378 382 public void adjustScanArea() { 379 383 SaneDeviceDescriptor d = (SaneDeviceDescriptor) scannerCombo.getSelectedItem(); … … 382 386 ScanPreviewDlg dlg = new ScanPreviewDlg( this, false ); 383 387 dlg.setScanner( dev ); 388 dlg.setScanArea( new Rectangle2D.Double( 30.0, 48.0, 160.0, 7.0 ) ); 389 dlg.addPropertyChangeListener("scanArea", new PropertyChangeListener() { 390 391 public void propertyChange( PropertyChangeEvent ev ) { 392 scanArea = (Rectangle2D) ev.getNewValue(); 393 } 394 }); 384 395 dlg.setVisible( true ); 396 385 397 } catch ( SaneException e ) { 386 398 return; -
src/main/pcapp/org/freecine/swingui/ScanTask.java
r50 r60 36 36 import org.freecine.sane.ScanParameter; 37 37 import java.awt.Point; 38 import java.awt.Rectangle;39 38 import java.awt.RenderingHints; 39 import java.awt.geom.Rectangle2D; 40 40 import java.awt.image.ColorModel; 41 41 import java.awt.image.DataBuffer; … … 44 44 import java.awt.image.RenderedImage; 45 45 import java.awt.image.SampleModel; 46 import java.io.File; 46 47 import java.io.IOException; 48 import java.util.Iterator; 49 import java.util.logging.Logger; 50 import javax.imageio.IIOImage; 51 import javax.imageio.ImageIO; 52 import javax.imageio.ImageWriteParam; 53 import javax.imageio.ImageWriter; 54 import javax.imageio.stream.ImageOutputStream; 47 55 import javax.media.jai.ImageLayout; 48 56 import javax.media.jai.JAI; … … 60 68 public class ScanTask extends Task<Void, Void> implements ScanAnalysisListener { 61 69 70 private static Logger log = Logger.getLogger(ScanTask.class.getName() ); 62 71 private SaneDevice dev; 63 private Rectangle scanArea;72 private Rectangle2D scanArea; 64 73 private Project prj; 65 74 private FilmMover filmMover; … … 71 80 @param prj the project in which scanned frames are added 72 81 */ 73 public ScanTask( SaneDevice dev, FilmMover mover, Rectangle scanArea, Project prj ) {82 public ScanTask( SaneDevice dev, FilmMover mover, Rectangle2D scanArea, Project prj ) { 74 83 super( Application.getInstance() ); 75 84 this.dev = dev; … … 106 115 while ( true ) { 107 116 PlanarImage img = scan(); 117 saveImage(img, new File( "/tmp/testimg.tif" ) ); 108 118 img = TransposeDescriptor.create( img, TransposeDescriptor.ROTATE_90, null ); 109 119 if ( isCancelled() ) { … … 146 156 dev.setOption( "mode", "Color" ); 147 157 dev.setOption( "depth", 16 ); 148 dev.setOption( "tl-x", new FixedPointNumber( 30 << 16 ) ); 149 dev.setOption( "tl-y", new FixedPointNumber( 48 << 16 ) ); 150 dev.setOption( "br-x", new FixedPointNumber( 190 << 16 ) ); 151 dev.setOption( "br-y", new FixedPointNumber( 55 << 16 ) ); 158 FixedPointNumber top = FixedPointNumber.valueOf( scanArea.getMinY() ); 159 FixedPointNumber left = FixedPointNumber.valueOf( scanArea.getMinX() ); 160 FixedPointNumber bot = FixedPointNumber.valueOf( scanArea.getMaxY() ); 161 FixedPointNumber right = FixedPointNumber.valueOf( scanArea.getMaxX() ); 162 163 // top = new FixedPointNumber( 48 << 16 ); 164 // left = new FixedPointNumber( 30 << 16 ); 165 // bot = new FixedPointNumber( 55 << 16 ); 166 // right = new FixedPointNumber( 190 << 16 ); 167 168 dev.setOption( "tl-x", left ); 169 dev.setOption( "tl-y", top ); 170 dev.setOption( "br-x", right ); 171 dev.setOption( "br-y", bot ); 152 172 dev.setOption( "resolution", 4800 ); 153 173 dev.setOption( "source", "Transparency Unit" ); … … 227 247 228 248 } 229 249 private void saveImage( RenderedImage img, File file ) { 250 // Find a writer for that file extensions 251 // Try to determine the file type based on extension 252 String ftype = "jpg"; 253 String imageFname = file.getName(); 254 int extIndex = imageFname.lastIndexOf( "." ) + 1; 255 if ( extIndex > 0 ) { 256 ftype = imageFname.substring( extIndex ); 257 } 258 259 ImageWriter writer = null; 260 Iterator iter = ImageIO.getImageWritersBySuffix( ftype ); 261 writer = (ImageWriter) iter.next(); 262 263 if ( writer != null ) { 264 ImageOutputStream ios = null; 265 try { 266 // Prepare output file 267 ios = ImageIO.createImageOutputStream( file ); 268 writer.setOutput( ios ); 269 // Set some parameters 270 ImageWriteParam param = writer.getDefaultWriteParam(); 271 writer.write( null, new IIOImage( img, null, null ), param ); 272 273 // Cleanup 274 ios.flush(); 275 276 } catch ( IOException ex ) { 277 log.severe( "Error saving image " + file.getAbsolutePath() + ": " 278 + ex.getMessage() ); 279 } finally { 280 if ( ios != null ) { 281 try { 282 ios.close(); 283 } catch ( IOException e ) { 284 log.severe( "Error closing output stream: " + e.getMessage() ); 285 } 286 } 287 writer.dispose(); 288 } 289 } 290 } 230 291 /** 231 292 Callback that is called by {@link ScanStrip} to inforrm about progress -
src/main/pcapp/org/freecine/swingui/resources/ScanPreviewDlg.properties
r59 r60 3 3 scanPreviewImage.Action.text=Scan Preview 4 4 scanPreviewImage.Action.shortDescription=Scan a new preview image 5 okBtn.text=jButton1 6 ok.Action.shortDescription=Set the can area 7 ok.Action.text=OK -
src/main/pcapp/org/freecine/swingui/resources/ScanTask.properties
r48 r60 4 4 initMessage = Initializing scanner 5 5 scanProgressMessage = Strip %1$d: Scanning, %2$d of %3$d lines scanned... 6 analysisProgressMessage = Strip %1$d: Analyzing image, % 1$d of %2$d lines ready...6 analysisProgressMessage = Strip %1$d: Analyzing image, %2$d of %3$d lines ready... 7 7 analysisCompleteMessage = Strip %1$d: Analysis complete, %2$d perforations found 8 8 movingFilmMsg = Moving film...
