Skip to content

Commit

Permalink
Should normally fix the issue in #3814
Browse files Browse the repository at this point in the history
  • Loading branch information
AlexisDrogoul committed May 31, 2023
1 parent 8e87a0f commit 7839e38
Show file tree
Hide file tree
Showing 6 changed files with 63 additions and 80 deletions.
52 changes: 7 additions & 45 deletions msi.gama.core/src/msi/gama/outputs/display/AWTDisplayGraphics.java
Expand Up @@ -41,11 +41,7 @@
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.awt.image.ImageObserver;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;

import org.locationtech.jts.awt.PointTransformation;
import org.locationtech.jts.awt.ShapeWriter;
Expand All @@ -55,10 +51,6 @@
import org.locationtech.jts.geom.Lineal;
import org.locationtech.jts.geom.Puntal;

import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;

import msi.gama.common.geometry.AxisAngle;
import msi.gama.common.geometry.GeometryUtils;
import msi.gama.common.interfaces.IAsset;
Expand Down Expand Up @@ -246,37 +238,22 @@ public Rectangle2D drawImage(final BufferedImage img, final DrawingAttributes at
curY = yFromModelUnitsToPixels(attributes.getLocation().getY());
}
imageTransform.translate(curX, curY);
double curWidth, curHeight;
int curWidth, curHeight;
if (attributes.getSize() == null) {
curWidth = getLayerWidth();
curHeight = getLayerHeight();
} else {
curWidth = wFromModelUnitsToPixels(attributes.getSize().getX());
curHeight = hFromModelUnitsToPixels(attributes.getSize().getY());
curWidth = (int) wFromModelUnitsToPixels(attributes.getSize().getX());
curHeight = (int) hFromModelUnitsToPixels(attributes.getSize().getY());
}

if (attributes.getAngle() != null) {
imageTransform.rotate(Maths.toRad * attributes.getAngle(), curWidth / 2d, curHeight / 2d);
// currentRenderer.rotate(Maths.toRad * attributes.getAngle(), curX + curWidth / 2d, curY + curHeight / 2d);
}

BufferedImage after = img;
Point2D.Double point = new Point2D.Double(curWidth, curHeight);
try {
Map<Point2D, BufferedImage> sizes = cache.get(img);
if (sizes.containsKey(point)) {
after = sizes.get(point);
} else {
after = resize(img, (int) Math.round(curWidth), (int) Math.round(curHeight));
}
} catch (ExecutionException e) {}

// imageTransform.scale(curWidth / img.getWidth(), curHeight / img.getHeight());
currentRenderer.drawImage(after, imageTransform, null);
// currentRenderer.drawImage(img, (int) FastMath.round(curX), (int) FastMath.round(curY), (int) curWidth,
// (int) curHeight, null);
if (curWidth != img.getWidth() || curHeight != img.getHeight()) {
imageTransform.scale((double) curWidth / img.getWidth(), (double) curHeight / img.getHeight());
}
currentRenderer.drawImage(img, imageTransform, null);
if (attributes.getBorder() != null) { drawGridLine(img, attributes.getBorder()); }
// currentRenderer.setTransform(saved);
rect.setRect(curX, curY, curWidth, curHeight);
if (highlight) { highlightRectangleInPixels(rect); }
return rect.getBounds2D();
Expand All @@ -303,21 +280,6 @@ public static BufferedImage resize(final BufferedImage img, final int newW, fina
return dimg;
}

/** The cache. */
@SuppressWarnings ({ "unchecked",
"unused" }) static LoadingCache<BufferedImage, Map<Point2D, BufferedImage>> cache =
CacheBuilder.<BufferedImage, Map<Point2D, BufferedImage>> newBuilder()
.expireAfterAccess(30, TimeUnit.SECONDS).removalListener(notif -> {
Map<Point2D, BufferedImage> map = (Map<Point2D, BufferedImage>) notif.getValue();
map.forEach((a, b) -> { b.flush(); });
}).build(new CacheLoader<>() {

@Override
public Map<Point2D, BufferedImage> load(final BufferedImage arg0) throws Exception {
return new HashMap<>();
}
});

/**
* Method drawString.
*
Expand Down
Expand Up @@ -60,6 +60,7 @@
import msi.gaml.statements.draw.DrawStatement.DrawValidator;
import msi.gaml.types.IType;
import msi.gaml.types.Types;
import ummisco.gama.dev.utils.DEBUG;

// A command that is used to draw shapes, figures, text on the display

Expand Down Expand Up @@ -404,7 +405,7 @@ private Rectangle2D privateExecuteIn(final IGraphicsScope scope) throws GamaRunt
} catch (final GamaRuntimeException e) {
throw e;
} catch (final Throwable e) {
java.lang.System.err.println("Error when drawing in a display : " + e.getMessage());
DEBUG.ERR("Error when drawing in a display : " + e.getMessage());
e.printStackTrace();
}
return null;
Expand Down
Expand Up @@ -21,12 +21,14 @@
import msi.gama.common.interfaces.IAsset;
import msi.gama.common.interfaces.IImageProvider;
import msi.gama.common.interfaces.IKeyword;
import msi.gama.common.interfaces.IValue;
import msi.gama.metamodel.topology.grid.GamaSpatialMatrix;
import msi.gama.precompiler.GamlAnnotations.doc;
import msi.gama.precompiler.GamlAnnotations.getter;
import msi.gama.precompiler.GamlAnnotations.variable;
import msi.gama.precompiler.GamlAnnotations.vars;
import msi.gama.runtime.IScope;
import msi.gama.runtime.exceptions.GamaRuntimeException;
import msi.gama.util.IList;
import msi.gama.util.file.IFieldMatrixProvider;
import msi.gama.util.matrix.GamaField;
Expand All @@ -53,10 +55,10 @@
name = IKeyword.WIDTH,
type = IType.INT,
doc = { @doc ("Returns the width (in pixels) of this image") }) })
public class GamaImage extends BufferedImage implements IImageProvider, IAsset, IFieldMatrixProvider {
public class GamaImage extends BufferedImage implements IImageProvider, IAsset, IFieldMatrixProvider, IValue {

/** The id. */
final String id;
String id;

/**
* Gets the id.
Expand Down Expand Up @@ -351,4 +353,22 @@ public static GamaImage from(final ColorModel cm, final WritableRaster raster, f
return new GamaImage(cm, raster, b, "raster" + System.currentTimeMillis());
}

/**
* Sets the id.
*
* @param string
* the new id
*/
public void setId(final String string) { id = string; }

@Override
public String stringValue(final IScope scope) throws GamaRuntimeException {
return id;
}

@Override
public GamaImage copy(final IScope scope) throws GamaRuntimeException {
return from(this, this.getAlpha(scope));
}

}
Expand Up @@ -15,6 +15,7 @@
import java.awt.Toolkit;
import java.awt.color.ColorSpace;
import java.awt.datatransfer.Clipboard;
import java.awt.image.BufferedImageOp;
import java.awt.image.ColorConvertOp;
import java.awt.image.ConvolveOp;
import java.awt.image.Kernel;
Expand Down Expand Up @@ -73,4 +74,8 @@ public interface ImageConstants {
*/
ColorConvertOp OP_GRAYSCALE = new ColorConvertOp(ColorSpace.getInstance(ColorSpace.CS_GRAY), null);

/** The descriptions. */
Map<BufferedImageOp, String> DESCRIPTIONS = Map.of(OP_DARKER, "darker", OP_ANTIALIAS, "antialiased", OP_BRIGHTER,
"brighter", OP_SHARPEN, "sharpened", OP_BLUR, "blurred", OP_GRAYSCALE, "grayscaled");

}
Expand Up @@ -50,6 +50,7 @@ static GamaImage apply(GamaImage src, final BufferedImageOp op) {
GamaImage result =
GamaImage.bestFor(src, (int) Math.round(bounds.getWidth()), (int) Math.round(bounds.getHeight()));
op.filter(src, result);
result.setId(src.getId() + DESCRIPTIONS.get(op));
return result;
}

Expand All @@ -71,6 +72,7 @@ protected static GamaImage copyToOptimalImage(final Image src) {
GamaImage result = GamaImage.ofDimensions(src.getWidth(null), src.getHeight(null), type);
Graphics g = result.getGraphics();
g.drawImage(src, 0, 0, null);
result.setId((src instanceof GamaImage gi ? gi.getId() : "image") + "optimized");
g.dispose();
return result;
}
Expand Down Expand Up @@ -123,6 +125,7 @@ static GamaImage rotate(final GamaImage src, final int typeOfRotation)
g2d.setRenderingHints(HINTS);
g2d.drawImage(src, tx, null);
g2d.dispose();
result.setId(src.getId() + "rotated" + typeOfRotation);
return result;
}

Expand Down Expand Up @@ -185,6 +188,7 @@ static GamaImage resize(final GamaImage src, final Mode resizeMode, int targetWi
} else {
result = ImageHelper.scaleImageIncrementally(src, targetWidth, targetHeight);
}
result.setId(src.getId() + "resized" + targetWidth + "|" + targetHeight);
return result;
}

Expand Down Expand Up @@ -226,7 +230,7 @@ static GamaImage scaleImageIncrementally(GamaImage src, final int targetWidth, f
src = incrementalImage;
hasReassignedSrc = true;
} while (currentWidth != targetWidth || currentHeight != targetHeight);

src.setId(src.getId() + "resized" + targetWidth + "|" + targetHeight);
return src;
}

Expand All @@ -247,7 +251,7 @@ static GamaImage scaleImageIncrementally(GamaImage src, final int targetWidth, f
public static GamaImage scaleImage(final Image bufferedImage, final int targetWidth, final int targetHeight) {
GamaImage result = GamaImage.bestFor(bufferedImage, targetWidth, targetHeight);
Graphics2D resultGraphics = result.createGraphics();
resultGraphics.setRenderingHints(ImageHelper.HINTS);
resultGraphics.setRenderingHints(ImageConstants.HINTS);
resultGraphics.drawImage(bufferedImage, 0, 0, targetWidth, targetHeight, null);
resultGraphics.dispose();
return result;
Expand Down
Expand Up @@ -401,6 +401,7 @@ public static GamaImage rotated(final IScope scope, final GamaImage image, final
g2.rotate(rads, w / 2, h / 2);
g2.drawImage(image, 0, 0, null);
g2.dispose();
rotated.setId(image.getId() + "rotated" + angleInDegrees);
return rotated;
}

Expand All @@ -419,18 +420,18 @@ public static GamaImage rotated(final IScope scope, final GamaImage image, final
@doc ("Returns the image tinted using the color passed in parameter. This effectively multiplies the colors of the image by it. The original image is left untouched")
@no_test
public static GamaImage tint(final IScope scope, final GamaImage image, final GamaColor color) {
GamaImage tintedSprite = GamaImage.ofDimensions(image.getWidth(), image.getHeight(), Transparency.TRANSLUCENT);
Graphics2D graphics = tintedSprite.createGraphics();
GamaImage result = GamaImage.ofDimensions(image.getWidth(), image.getHeight(), Transparency.TRANSLUCENT);
Graphics2D graphics = result.createGraphics();
graphics.drawImage(image, 0, 0, null);
graphics.dispose();
ColorModel cm = tintedSprite.getColorModel();
WritableRaster raster = tintedSprite.getRaster();
ColorModel cm = result.getColorModel();
WritableRaster raster = result.getRaster();
float r = color.getRed() / 255f;
float g = color.getGreen() / 255f;
float b = color.getBlue() / 255f;
float a = color.getAlpha() / 255f;
for (int i = 0; i < tintedSprite.getWidth(); i++) {
for (int j = 0; j < tintedSprite.getHeight(); j++) {
for (int i = 0; i < result.getWidth(); i++) {
for (int j = 0; j < result.getHeight(); j++) {
int ax = cm.getAlpha(raster.getDataElements(i, j, null));
int rx = cm.getRed(raster.getDataElements(i, j, null));
int gx = cm.getGreen(raster.getDataElements(i, j, null));
Expand All @@ -439,10 +440,11 @@ public static GamaImage tint(final IScope scope, final GamaImage image, final Ga
gx *= g;
bx *= b;
ax *= a;
tintedSprite.setRGB(i, j, ax << 24 | rx << 16 | gx << 8 | bx);
result.setRGB(i, j, ax << 24 | rx << 16 | gx << 8 | bx);
}
}
return tintedSprite;
result.setId(image.getId() + "tinted" + color.getRGB());
return result;
}

/**
Expand Down Expand Up @@ -476,30 +478,17 @@ public static GamaImage tint(final IScope scope, final GamaImage image, final Ga
public static GamaImage tint(final IScope scope, final GamaImage image, final GamaColor color, final double ratio) {
int w = image.getWidth();
int h = image.getHeight();
GamaImage dyed = GamaImage.ofDimensions(w, h, BufferedImage.TYPE_INT_ARGB);
Graphics2D g = dyed.createGraphics();
GamaImage result = GamaImage.ofDimensions(w, h, BufferedImage.TYPE_INT_ARGB);
Graphics2D g = result.createGraphics();
g.drawImage(image, 0, 0, null);
g.setComposite(AlphaComposite.SrcAtop.derive(Math.min(1f, Math.max((float) ratio, 0f))));
g.setColor(color);
g.fillRect(0, 0, w, h);
g.dispose();
return dyed;
result.setId(image.getId() + "tinted" + color + "|" + ratio);
return result;
}

/**
* Blend.
*
* @param scope
* the scope
* @param image
* the image
* @param overlay
* the overlay
* @param ratio
* the ratio
* @return the gama image
*/

/**
* Blend.
*
Expand All @@ -526,14 +515,15 @@ public static GamaImage tint(final IScope scope, final GamaImage image, final Ga
@no_test
public static GamaImage blend(final IScope scope, final GamaImage image, final GamaImage overlay,
final double ratio) {
GamaImage composed = ImageHelper.copyToOptimalImage(image);
Graphics2D g2d = composed.createGraphics();
GamaImage result = ImageHelper.copyToOptimalImage(image);
Graphics2D g2d = result.createGraphics();
g2d.setComposite(AlphaComposite.SrcOver.derive(Math.min(1f, Math.max((float) ratio, 0f))));
int x = (composed.getWidth() - overlay.getWidth()) / 2;
int y = (composed.getHeight() - overlay.getHeight()) / 2;
int x = (result.getWidth() - overlay.getWidth()) / 2;
int y = (result.getHeight() - overlay.getHeight()) / 2;
g2d.drawImage(overlay, x, y, null);
g2d.dispose();
return composed;
result.setId(image.getId() + "|" + overlay.getId());
return result;
}

/**
Expand Down Expand Up @@ -605,6 +595,7 @@ public static GamaImage cropped(final IScope scope, final GamaImage image, final
Graphics g = result.getGraphics();
g.drawImage(image, 0, 0, width, height, x, y, x + width, y + height, null);
g.dispose();
result.setId(image.getId() + "crop" + ox + "|" + oy + "|" + ow + "|" + oh);
return result;
}

Expand Down

0 comments on commit 7839e38

Please sign in to comment.