hey Mike,

how about cropping first and scaling only the part shown?.. ede

On October 12, 2020 9:19:38 PM GMT+02:00, jump-pilot-svn--- via 
Jump-pilot-devel <jump-pilot-devel@lists.sourceforge.net> wrote:
>Revision: 6596
>          http://sourceforge.net/p/jump-pilot/code/6596
>Author:   michaudm
>Date:     2020-10-12 19:19:38 +0000 (Mon, 12 Oct 2020)
>Log Message:
>-----------
>Keep double parameters as long as possible (does not solve the pb
>described in #507)
>
>Modified Paths:
>--------------
>core/trunk/src/com/vividsolutions/jump/workbench/imagery/geoimg/GeoImage.java
>
>Modified:
>core/trunk/src/com/vividsolutions/jump/workbench/imagery/geoimg/GeoImage.java
>===================================================================
>---
>core/trunk/src/com/vividsolutions/jump/workbench/imagery/geoimg/GeoImage.java  
>2020-10-12
>15:05:32 UTC (rev 6595)
>+++
>core/trunk/src/com/vividsolutions/jump/workbench/imagery/geoimg/GeoImage.java  
>2020-10-12
>19:19:38 UTC (rev 6596)
>@@ -37,6 +37,7 @@
> import java.awt.Rectangle;
> import java.awt.RenderingHints;
> import java.awt.geom.AffineTransform;
>+import java.awt.geom.NoninvertibleTransformException;
> import java.awt.image.BufferedImage;
> import java.awt.image.RenderedImage;
> import java.awt.image.renderable.ParameterBlock;
>@@ -44,10 +45,15 @@
> 
> import javax.media.jai.JAI;
> import javax.media.jai.RenderedOp;
>+import javax.media.jai.operator.AffineDescriptor;
> 
>+import com.vividsolutions.jts.geom.Coordinate;
> import com.vividsolutions.jts.geom.Envelope;
>+import com.vividsolutions.jts.geom.util.AffineTransformation;
>+import com.vividsolutions.jts.geom.util.AffineTransformationBuilder;
> import com.vividsolutions.jump.JUMPException;
> import com.vividsolutions.jump.feature.Feature;
>+import com.vividsolutions.jump.util.Timer;
> import com.vividsolutions.jump.workbench.imagery.ReferencedImage;
>import
>com.vividsolutions.jump.workbench.imagery.ReferencedImageException;
> import com.vividsolutions.jump.workbench.model.Disposable;
>@@ -57,7 +63,7 @@
>public class GeoImage implements ReferencedImage, Disposable,
>AlphaSetting {
>   private GeoReferencedRaster gtr;
>   private int alpha = 255;
>-  private float last_scale;
>+  private double last_scale;
>   private RenderedOp last_scale_img;
>   private Envelope last_img_env;
>   private RenderedImage last_rendering;
>@@ -92,6 +98,7 @@
>public synchronized void paint(Feature f, java.awt.Graphics2D g,
>Viewport viewport)
>       throws ReferencedImageException {
> 
>+    //long t0 = Timer.now();
>     try {
>       // update image envelope, either use geometry's or image's
>       // this allows moving the image via geometry movement
>@@ -109,17 +116,17 @@
>       // + Integer.toHexString(img.hashCode()));
> 
>       // get current scale
>-      final float scale = (float) viewport.getScale();
>+      final double scale = viewport.getScale();
>       // get current viewport area
> Envelope envModel_viewport = viewport.getEnvelopeInModelCoordinates();
> 
>       // if nothing changed, no reason to rerender the whole shebang
>       // this is mainly the case when OJ last and regained focus
>-      if (last_scale == scale && last_img_env instanceof Envelope
>-          && last_img_env.equals(envImage) && last_vwp_env instanceof
>Envelope
>+      if (last_scale == scale && last_img_env != null
>+          && last_img_env.equals(envImage) && last_vwp_env != null
>           && last_vwp_env.equals(envModel_viewport)
>-          && last_rendering instanceof RenderedImage
>-          && last_transform instanceof AffineTransform) {
>+          && last_rendering != null
>+          && last_transform != null) {
>         draw(g, null);
>         return;
>       }
>@@ -132,7 +139,7 @@
>     // reuse a cached version if scale and img_envelope didn't changed
>         // speeds up panning, window resizing
>         if (last_scale == scale && last_scale_img != null
>-            && last_img_env instanceof Envelope
>+            && last_img_env != null
>             && last_img_env.equals(envImage)) {
>           img = last_scale_img;
> //          System.out.println("GI: USE SCALE CACHE");
>@@ -140,8 +147,8 @@
> //          System.out.println("GI: NO SCALE CACHE");
> 
>           // First, scale the original image
>-          float scaleX = scale * (float)
>gtr.getDblModelUnitsPerRasterUnit_X();
>-          float scaleY = scale * (float)
>gtr.getDblModelUnitsPerRasterUnit_Y();
>+          double scaleX = scale *
>gtr.getDblModelUnitsPerRasterUnit_X();
>+          double scaleY = scale *
>gtr.getDblModelUnitsPerRasterUnit_Y();
> 
>           // calculate predicted dimensions
>           double scaledW = scaleX * src_img.getWidth();
>@@ -157,7 +164,7 @@
> 
>           // we cache an overview here for big pictures 
>           // speeds up situations when the whole picture is shown
>-          float scaleX_toUse, scaleY_toUse;
>+          double scaleX_toUse, scaleY_toUse;
>           RenderedImage scale_src_img;
>if ((imgW > 2000 || imgH > 2000) && scaledW < 2000 && scaledH < 2000 )
>{
> //            System.out.println("GI: USE FULL SCALE CACHE");
>@@ -165,9 +172,9 @@
>// this is faster than having JAI create it from scratch from big
>datasets
>             if (full_scale_img == null) {
>               if (imgW > imgH) {
>-                full_scale = 1 / (imgW / 2000d);
>+                full_scale = 2000d / imgW;
>               } else {
>-                full_scale = 1 / (imgH / 2000d);
>+                full_scale = 2000d / imgH;
>               }
>               // subsample average gives a smoothly resized image
>               pb = new ParameterBlock();
>@@ -178,14 +185,14 @@
> //              System.out.println("GI full scale img: "
> //                  + full_scale_img.getWidth());
>             }
>-            scaleX_toUse = (float) scaleX / (float) full_scale;
>-            scaleY_toUse = (float) scaleY / (float) full_scale;
>+            scaleX_toUse = scaleX / full_scale;
>+            scaleY_toUse = scaleY / full_scale;
>             scale_src_img = full_scale_img;
>           }
>           // scale the original 
>           else{
>-            scaleX_toUse = (float) scaleX;
>-            scaleY_toUse = (float) scaleY;
>+            scaleX_toUse = scaleX;
>+            scaleY_toUse = scaleY;
>             scale_src_img = src_img;
>           }
> 
>@@ -195,8 +202,8 @@
>           // so use slow and qualitative inferior bicubic instead
>           // or NOT, to f**g slow, use default interpolation
>           if (scaleX > 0.1 || scaleY > 0.1) {
>-            pb.add(scaleX_toUse);
>-            pb.add(scaleY_toUse);
>+            pb.add((float)scaleX_toUse);
>+            pb.add((float)scaleY_toUse);
>             pb.add(0f);
>             pb.add(0f);
>             // Interpolation interp = Interpolation
>@@ -204,8 +211,8 @@
>             // pb.add(interp); // add interpolation method
>             img = JAI.create("scale", pb, hints);
>           } else {
>-            pb.add((double) (scaleX_toUse));
>-            pb.add((double) (scaleY_toUse));
>+            pb.add(scaleX_toUse);
>+            pb.add(scaleY_toUse);
>             img = JAI.create("subsampleaverage", pb, hints);
>           }
> 
>@@ -244,13 +251,13 @@
>double ratio_cropW = envModel_viewport.getWidth() /
>envImage.getWidth();
>double ratio_cropH = envModel_viewport.getHeight() /
>envImage.getHeight();
> 
>-      float raster_cropX = (int) (ratio_cropX * img.getWidth());
>-      float raster_cropY = (int) (ratio_cropY * img.getHeight());
>-      float raster_cropW = (int) (ratio_cropW * img.getWidth());
>-      float raster_cropH = (int) (ratio_cropH * img.getHeight());
>+      double raster_cropX = ratio_cropX * img.getWidth();
>+      double raster_cropY = ratio_cropY * img.getHeight();
>+      double raster_cropW = ratio_cropW * img.getWidth();
>+      double raster_cropH = ratio_cropH * img.getHeight();
> 
>-      float raster_offsetX = 0;
>-      float raster_offsetY = 0;
>+      double raster_offsetX = 0;
>+      double raster_offsetY = 0;
> 
>       if (raster_cropX < 0) {
>         raster_offsetX = -raster_cropX;
>@@ -260,24 +267,30 @@
>         raster_offsetY = -raster_cropY;
>         raster_cropY = 0;
>       }
>+      raster_cropX = Math.min((float)raster_cropX,
>(float)img.getWidth());
>+      raster_cropY = Math.min((float)raster_cropY,
>(float)img.getHeight());
>       raster_cropW = Math
>-          .min(raster_cropW, img.getWidth() - (int) raster_cropX);
>-      raster_cropH = Math.min(raster_cropH, img.getHeight()
>-          - (int) raster_cropY);
>+          .min((float)raster_cropW, (float)img.getWidth() - /*(int)*/
>raster_cropX);
>+      raster_cropH = Math.min((float)raster_cropH,
>(float)img.getHeight()
>+          - /*(int)*/ raster_cropY);
> 
>       pb = new ParameterBlock();
>       pb.addSource(img);
>-      pb.add(raster_cropX);
>-      pb.add(raster_cropY);
>-      pb.add(raster_cropW);
>-      pb.add(raster_cropH);
>+      //System.out.println("cropx " + (float)raster_cropX);
>+      //System.out.println("cropy " + (float)raster_cropY);
>+      //System.out.println("cropw " + (float)raster_cropW + " " +
>(img.getWidth() - /*(int)*/ raster_cropX));
>+      //System.out.println("croph " + (float)raster_cropH + " " +
>(img.getHeight() - /*(int)*/ raster_cropY));
>+      pb.add((float)raster_cropX);
>+      pb.add((float)raster_cropY);
>+      pb.add((float)raster_cropW);
>+      pb.add((float)raster_cropH);
>       img = JAI.create("crop", pb, null);
> 
>       // move the image to the model coordinates
>       pb = new ParameterBlock();
>       pb.addSource(img);
>-      pb.add(raster_offsetX - img.getMinX());
>-      pb.add(raster_offsetY - img.getMinY());
>+      pb.add((float)(raster_offsetX - img.getMinX()));
>+      pb.add((float)(raster_offsetY - img.getMinY()));
>       img = JAI.create("translate", pb, null);
> 
>       // cache the current rendering here as used in the
>@@ -288,6 +301,7 @@
> 
>       // eventually draw the image, let g render the chain
>       draw(g, img);
>+      //System.out.printf("Display at %f in %d ms%n", scale,
>Timer.milliSecondsSince(t0));
> 
>     } catch (Exception ex) {
>       throw new ReferencedImageException(ex);
>@@ -294,6 +308,77 @@
>     }
>   }
> 
>+  // [mmichaud 2020-10-12] try to make image display more precise
>using double-based
>+  // affine transform, but the code does not take advanatage of jai
>subsample used in
>+  // the previous code and is much slower
>+  //RenderedImage cached2000px = null;
>+  //public synchronized void paint(Feature f, java.awt.Graphics2D g,
>Viewport viewport)
>+  //        throws ReferencedImageException {
>+  //  long t0 = Timer.now();
>+  //  long t1 = 0L;
>+  //  // Image enveloppe in model coordinates
>+  //  Envelope imageEnv = gtr.getEnvelope(f);
>+  //  RenderedOp op = gtr.getRenderedOp();
>+  //  RenderedImage im = op;
>+  //  RenderingHints hints = gtr.createCacheRenderingHints();
>+  //
>+  //  // Size of an image pixel in the Model (ground coordinates)
>+  //  double pixelSizeInModelX = imageEnv.getWidth()/op.getWidth();
>+  //  double pixelSizeInModelY = imageEnv.getHeight()/op.getHeight();
>+  //  double scale = viewport.getScale();
>+  //  // Size of an image pixel in the screen model (number of screen
>pixel for one image pixel)
>+  //  double pixelSizeInViewX = pixelSizeInModelX * scale;
>+  //  double pixelSizeInViewY = pixelSizeInModelY * scale;
>+  //  // Short circuit : if the full image is < 1 screen pixel, return
>+  //  if (pixelSizeInViewX*im.getWidth() < 0.5 &&
>pixelSizeInViewY*im.getHeight() < 0.5) {
>+  //    System.out.println("Full image < 1 px");
>+  //    return;
>+  //  }
>+  //
>+  //  if ((im.getWidth() > 2000 || im.getHeight() > 2000) &&
>pixelSizeInViewX < 1 && pixelSizeInViewY < 1) {
>+  //    if (cached2000px == null) {
>+  //      full_scale = 2000d / Math.max(im.getWidth(),
>im.getHeight());
>+  //      ParameterBlock pb = new ParameterBlock();
>+  //      pb.addSource(im);
>+  //      pb.add(full_scale); // x scale factor
>+  //      pb.add(full_scale); // y scale factor
>+  //      cached2000px = JAI.create("subsampleaverage", pb, null);
>+  //    }
>+  //    im = cached2000px;
>+  //  }
>+  //
>+  //  System.out.println("Image " + im.getWidth() + " x " +
>im.getHeight());
>+  //
>+  //  try {
>+  //    AffineTransform model2view =
>viewport.getModelToViewTransform();
>+  //    AffineTransformation imageToModel = new
>AffineTransformationBuilder(
>+  //            new Coordinate(0.0, 0.0),
>+  //            new Coordinate(im.getWidth(), 0.0),
>+  //            new Coordinate(0.0, im.getHeight()),
>+  //            new Coordinate(imageEnv.getMinX(),
>imageEnv.getMaxY()),
>+  //            new Coordinate(imageEnv.getMaxX(),
>imageEnv.getMaxY()),
>+  //            new Coordinate(imageEnv.getMinX(), imageEnv.getMinY())
>+  //    ).getTransformation();
>+  //
>+  //    AffineTransform image2view = new AffineTransform(
>+  //            imageToModel.getMatrixEntries()[0],
>+  //            imageToModel.getMatrixEntries()[3],
>+  //            imageToModel.getMatrixEntries()[1],
>+  //            imageToModel.getMatrixEntries()[4],
>+  //            imageToModel.getMatrixEntries()[2],
>+  //            imageToModel.getMatrixEntries()[5]
>+  //    );
>+  //
>+  //    image2view.preConcatenate(model2view);
>+  //    im = AffineDescriptor.create(im,image2view, null,null, hints);
>+  //    g.drawRenderedImage(im, new AffineTransform());
>+  //
>+  //    System.out.printf("Display at %f (jai %d) (%dx%d) in %d ms%n",
>scale, t1, im.getWidth(), im.getHeight(), Timer.milliSecondsSince(t0));
>+  //  } catch (NoninvertibleTransformException ex) {
>+  //    throw new ReferencedImageException(ex);
>+  //  }
>+  //}
>+
>   private void draw(Graphics2D g, RenderedImage img) {
>     Composite composite = g.getComposite();
>     // setup transparency
>@@ -302,7 +387,7 @@
>     // The image has been translated and scaled by JAI
>     // already. Just draw it with an identity transformation.
>     AffineTransform aft;
>-    if (img instanceof RenderedImage){
>+    if (img != null) {
>       aft = new AffineTransform();
>     }
>     // no img given? paint cached last rendering again
>
>
>
>_______________________________________________
>Jump-pilot-devel mailing list
>Jump-pilot-devel@lists.sourceforge.net
>https://lists.sourceforge.net/lists/listinfo/jump-pilot-devel


_______________________________________________
Jump-pilot-devel mailing list
Jump-pilot-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/jump-pilot-devel

Reply via email to