mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-19 12:18:00 +00:00
- #0000743: OutOfMemoryError caused by image ResampleOp in FImagePanel. (http://www.cardforge.org/bugz/view.php?id=743)
This commit is contained in:
@@ -41,7 +41,7 @@ import com.mortennobel.imagescaling.ResampleOp;
|
|||||||
* <p>
|
* <p>
|
||||||
* Options to scale and rotate the image are available if required.
|
* Options to scale and rotate the image are available if required.
|
||||||
*
|
*
|
||||||
* @version $Id:$
|
* @version $Id$
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("serial")
|
@SuppressWarnings("serial")
|
||||||
@@ -55,6 +55,11 @@ public class FImagePanel extends JPanel {
|
|||||||
// Remains the same regardless of any transformations that might be applied to it.
|
// Remains the same regardless of any transformations that might be applied to it.
|
||||||
private BufferedImage sourceImage = null;
|
private BufferedImage sourceImage = null;
|
||||||
|
|
||||||
|
// Resampling is an expensive operation so keep a copy of last resampled image and
|
||||||
|
// use this for repaints if image has not been resized or changed.
|
||||||
|
private BufferedImage scaledImage = null;
|
||||||
|
private boolean isResampleEnabled = true;
|
||||||
|
|
||||||
private double imageScale = 1;
|
private double imageScale = 1;
|
||||||
private int degreesOfRotation = 0;
|
private int degreesOfRotation = 0;
|
||||||
|
|
||||||
@@ -69,12 +74,6 @@ public class FImagePanel extends JPanel {
|
|||||||
setResizeListener();
|
setResizeListener();
|
||||||
};
|
};
|
||||||
|
|
||||||
public void clearImage() {
|
|
||||||
this.sourceImage = null;
|
|
||||||
this.imageScale = 1;
|
|
||||||
repaint();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This timer is used to identify when resizing has finished.
|
* This timer is used to identify when resizing has finished.
|
||||||
* <p>
|
* <p>
|
||||||
@@ -95,6 +94,7 @@ public class FImagePanel extends JPanel {
|
|||||||
private void doResizedFinished() {
|
private void doResizedFinished() {
|
||||||
this.resizingTimer.stop();
|
this.resizingTimer.stop();
|
||||||
this.isResizing = false;
|
this.isResizing = false;
|
||||||
|
this.isResampleEnabled = true;
|
||||||
this.repaint();
|
this.repaint();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -118,11 +118,11 @@ public class FImagePanel extends JPanel {
|
|||||||
* This means the image can only have either a vertical or horizontal orientation.
|
* This means the image can only have either a vertical or horizontal orientation.
|
||||||
*/
|
*/
|
||||||
public void setImage(BufferedImage image, int initialRotation, AutoSizeImageMode autoSizeMode) {
|
public void setImage(BufferedImage image, int initialRotation, AutoSizeImageMode autoSizeMode) {
|
||||||
if (this.sourceImage != image) {
|
if (this.sourceImage != image || this.degreesOfRotation != initialRotation || this.autoSizeMode != autoSizeMode) {
|
||||||
|
isResampleEnabled = true;
|
||||||
this.autoSizeMode = autoSizeMode;
|
this.autoSizeMode = autoSizeMode;
|
||||||
if (initialRotation > 0) { setRotation(initialRotation); }
|
if (initialRotation > 0) { setRotation(initialRotation); }
|
||||||
this.sourceImage = image;
|
this.sourceImage = image;
|
||||||
setImageScale();
|
|
||||||
repaint();
|
repaint();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -165,9 +165,11 @@ public class FImagePanel extends JPanel {
|
|||||||
* This means the image can only have either a vertical or horizontal orientation.
|
* This means the image can only have either a vertical or horizontal orientation.
|
||||||
*/
|
*/
|
||||||
public void setRotation(int degrees) {
|
public void setRotation(int degrees) {
|
||||||
this.degreesOfRotation = ImageUtil.getRotationToNearest(degrees, 90);
|
if (this.degreesOfRotation != degrees) {
|
||||||
setImageScale();
|
this.degreesOfRotation = ImageUtil.getRotationToNearest(degrees, 90);
|
||||||
repaint();
|
isResampleEnabled = true;
|
||||||
|
repaint();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -217,19 +219,26 @@ public class FImagePanel extends JPanel {
|
|||||||
/**
|
/**
|
||||||
* Uses Morten Nobel's java-image-scaling library to resize image.
|
* Uses Morten Nobel's java-image-scaling library to resize image.
|
||||||
* <p>
|
* <p>
|
||||||
* This produces superior quality to affine scaling as image sizes
|
* This produces superior quality to affine scaling especially as
|
||||||
* are reduced but at the cost of performance.
|
* image sizes are reduced but at the cost of performance.
|
||||||
|
* <p>
|
||||||
|
* You cannot legislate for when this will be called since it depends
|
||||||
|
* on how often paintComponent() is invoked and any number of external
|
||||||
|
* events can cause this to happen. But resampling is an expensive operation
|
||||||
|
* so use an existing copy if the image has not changed or been resized.
|
||||||
*/
|
*/
|
||||||
private BufferedImage getResampledImage() {
|
private BufferedImage getResampledImage() {
|
||||||
BufferedImage scaledImage = null;
|
|
||||||
if (this.imageScale != 1) {
|
if (this.imageScale != 1) {
|
||||||
DimensionConstrain constrain = DimensionConstrain.createRelativeDimension((float)this.imageScale);
|
if (isResampleEnabled) {
|
||||||
ResampleOp resampler = new ResampleOp(constrain);
|
isResampleEnabled = false;
|
||||||
scaledImage = resampler.filter(sourceImage, null);
|
DimensionConstrain constrain = DimensionConstrain.createRelativeDimension((float)this.imageScale);
|
||||||
|
ResampleOp resampler = new ResampleOp(constrain);
|
||||||
|
this.scaledImage = resampler.filter(sourceImage, null);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
scaledImage = sourceImage;
|
this.scaledImage = sourceImage;
|
||||||
}
|
}
|
||||||
return scaledImage;
|
return this.scaledImage;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -319,10 +328,14 @@ public class FImagePanel extends JPanel {
|
|||||||
private void setImageScale() {
|
private void setImageScale() {
|
||||||
if (this.sourceImage != null) {
|
if (this.sourceImage != null) {
|
||||||
if (this.autoSizeMode != AutoSizeImageMode.OFF) {
|
if (this.autoSizeMode != AutoSizeImageMode.OFF) {
|
||||||
this.imageScale = ImageUtil.getBestFitScale(getSourceImageSize(), this.getSize());
|
Double newScale = ImageUtil.getBestFitScale(getSourceImageSize(), this.getSize());
|
||||||
if (this.imageScale == 0) { this.imageScale = 1; };
|
if (newScale != this.imageScale) {
|
||||||
if (this.autoSizeMode == AutoSizeImageMode.SOURCE && this.imageScale > 1) {
|
isResampleEnabled = true;
|
||||||
this.imageScale = 1;
|
this.imageScale = newScale;
|
||||||
|
if (newScale == 0) { this.imageScale = 1; };
|
||||||
|
if (this.autoSizeMode == AutoSizeImageMode.SOURCE && newScale > 1) {
|
||||||
|
this.imageScale = 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user