mirror of
https://github.com/correl/mage.git
synced 2025-01-12 11:08:01 +00:00
Drastically simplify ScaledImagePanel by having it just use the resized image cache
All the current behavior of ScaledImagePanel seems to be useless, since the source images are static, so we can just use the highest quality scaling possible and cache the result using TransformedImageCache.
This commit is contained in:
parent
e3d84ca212
commit
4b190eeaf4
2 changed files with 6 additions and 174 deletions
|
@ -52,8 +52,6 @@ import mage.view.PermanentView;
|
|||
import mage.view.StackAbilityView;
|
||||
import net.java.truevfs.access.TFile;
|
||||
import org.apache.log4j.Logger;
|
||||
import org.mage.card.arcane.ScaledImagePanel.MultipassType;
|
||||
import org.mage.card.arcane.ScaledImagePanel.ScalingType;
|
||||
import static org.mage.plugins.card.constants.Constants.THUMBNAIL_SIZE_FULL;
|
||||
import org.mage.plugins.card.dl.sources.DirectLinksForDownload;
|
||||
import org.mage.plugins.card.images.ImageCache;
|
||||
|
@ -304,9 +302,6 @@ public class CardPanel extends MagePermanent implements MouseListener, MouseMoti
|
|||
imagePanel = new ScaledImagePanel();
|
||||
imagePanel.setBorder(BorderFactory.createLineBorder(Color.white));
|
||||
add(imagePanel);
|
||||
imagePanel.setScaleLarger(true);
|
||||
imagePanel.setScalingType(ScalingType.nearestNeighbor);
|
||||
imagePanel.setScalingMultiPassType(MultipassType.none);
|
||||
|
||||
String cardType = getType(newGameCard);
|
||||
tooltipText.setText(getText(cardType, newGameCard));
|
||||
|
@ -387,7 +382,7 @@ public class CardPanel extends MagePermanent implements MouseListener, MouseMoti
|
|||
titleText.setText(!displayTitleAnyway && hasImage ? "" : card.getName());
|
||||
}
|
||||
|
||||
private void setImage(Image srcImage) {
|
||||
private void setImage(BufferedImage srcImage) {
|
||||
synchronized (imagePanel) {
|
||||
imagePanel.setImage(srcImage);
|
||||
repaint();
|
||||
|
@ -413,10 +408,6 @@ public class CardPanel extends MagePermanent implements MouseListener, MouseMoti
|
|||
return zone;
|
||||
}
|
||||
|
||||
public void setScalingType(ScalingType scalingType) {
|
||||
imagePanel.setScalingType(scalingType);
|
||||
}
|
||||
|
||||
public void setDisplayEnabled(boolean displayEnabled) {
|
||||
this.displayEnabled = displayEnabled;
|
||||
}
|
||||
|
@ -619,12 +610,6 @@ public class CardPanel extends MagePermanent implements MouseListener, MouseMoti
|
|||
|
||||
ptText.setLocation(cardXOffset + ptX - TEXT_GLOW_SIZE / 2 - offsetX, cardYOffset + ptY - TEXT_GLOW_SIZE / 2);
|
||||
}
|
||||
|
||||
if (isAnimationPanel || cardWidth < 200) {
|
||||
imagePanel.setScalingType(ScalingType.nearestNeighbor);
|
||||
} else {
|
||||
imagePanel.setScalingType(ScalingType.bilinear);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -7,188 +7,35 @@ import java.awt.RenderingHints;
|
|||
import java.awt.image.BufferedImage;
|
||||
|
||||
import javax.swing.JPanel;
|
||||
import mage.client.util.TransformedImageCache;
|
||||
|
||||
public class ScaledImagePanel extends JPanel {
|
||||
private static final long serialVersionUID = -1523279873208605664L;
|
||||
private volatile Image srcImage;
|
||||
|
||||
private ScalingType scalingType = ScalingType.bilinear;
|
||||
private boolean scaleLarger;
|
||||
private MultipassType multiPassType = MultipassType.bilinear;
|
||||
private volatile BufferedImage srcImage;
|
||||
|
||||
public ScaledImagePanel () {
|
||||
super(false);
|
||||
setOpaque(false);
|
||||
}
|
||||
|
||||
public void setImage(Image srcImage) {
|
||||
public void setImage(BufferedImage srcImage) {
|
||||
this.srcImage = srcImage;
|
||||
}
|
||||
|
||||
public void clearImage () {
|
||||
srcImage = null;
|
||||
repaint();
|
||||
}
|
||||
|
||||
public void setScalingMultiPassType (MultipassType multiPassType) {
|
||||
this.multiPassType = multiPassType;
|
||||
}
|
||||
|
||||
public void setScalingType (ScalingType scalingType) {
|
||||
this.scalingType = scalingType;
|
||||
}
|
||||
|
||||
public void setScaleLarger (boolean scaleLarger) {
|
||||
this.scaleLarger = scaleLarger;
|
||||
}
|
||||
|
||||
public boolean hasImage () {
|
||||
return srcImage != null;
|
||||
}
|
||||
|
||||
private ScalingInfo getScalingInfo () {
|
||||
int panelWidth = getWidth();
|
||||
int panelHeight = getHeight();
|
||||
int srcWidth = srcImage.getWidth(null);
|
||||
int srcHeight = srcImage.getHeight(null);
|
||||
int targetWidth = srcWidth;
|
||||
int targetHeight = srcHeight;
|
||||
if (scaleLarger || srcWidth > panelWidth || srcHeight > panelHeight) {
|
||||
targetWidth = Math.round(panelHeight * (srcWidth / (float)srcHeight));
|
||||
if (targetWidth > panelWidth) {
|
||||
targetHeight = Math.round(panelWidth * (srcHeight / (float)srcWidth));
|
||||
targetWidth = panelWidth;
|
||||
} else {
|
||||
targetHeight = panelHeight;
|
||||
}
|
||||
}
|
||||
ScalingInfo info = new ScalingInfo();
|
||||
info.targetWidth = targetWidth;
|
||||
info.targetHeight = targetHeight;
|
||||
info.srcWidth = srcWidth;
|
||||
info.srcHeight = srcHeight;
|
||||
info.x = panelWidth / 2 - targetWidth / 2;
|
||||
info.y = panelHeight / 2 - targetHeight / 2;
|
||||
return info;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void paint (Graphics g) {
|
||||
if (srcImage == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
Graphics2D g2 = (Graphics2D)g.create();
|
||||
ScalingInfo info = getScalingInfo();
|
||||
|
||||
switch (scalingType) {
|
||||
case nearestNeighbor:
|
||||
scaleWithDrawImage(g2, info, RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR);
|
||||
break;
|
||||
case bilinear:
|
||||
scaleWithDrawImage(g2, info, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
|
||||
break;
|
||||
case bicubic:
|
||||
scaleWithDrawImage(g2, info, RenderingHints.VALUE_INTERPOLATION_BICUBIC);
|
||||
break;
|
||||
case areaAveraging:
|
||||
scaleWithGetScaledInstance(g2, info, Image.SCALE_AREA_AVERAGING);
|
||||
break;
|
||||
case replicate:
|
||||
scaleWithGetScaledInstance(g2, info, Image.SCALE_REPLICATE);
|
||||
break;
|
||||
}
|
||||
g.drawImage(TransformedImageCache.getResizedImage(srcImage, getWidth(), getHeight()), 0, 0, null);
|
||||
}
|
||||
|
||||
private void scaleWithGetScaledInstance (Graphics2D g2, ScalingInfo info, int hints) {
|
||||
Image scaledImage = srcImage.getScaledInstance(info.targetWidth, info.targetHeight, hints);
|
||||
g2.drawImage(scaledImage, info.x, info.y, null);
|
||||
}
|
||||
|
||||
private void scaleWithDrawImage (Graphics2D g2, ScalingInfo info, Object hint) {
|
||||
g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, hint);
|
||||
|
||||
int tempDestWidth = info.srcWidth / 2, tempDestHeight = info.srcHeight / 2;
|
||||
if (tempDestWidth < info.targetWidth) {
|
||||
tempDestWidth = info.targetWidth;
|
||||
}
|
||||
if (tempDestHeight < info.targetHeight) {
|
||||
tempDestHeight = info.targetHeight;
|
||||
}
|
||||
|
||||
// If not doing multipass or multipass only needs a single pass, just scale it once directly to the panel surface.
|
||||
if (multiPassType == MultipassType.none || (tempDestWidth == info.targetWidth && tempDestHeight == info.targetHeight)) {
|
||||
g2.drawImage(srcImage, info.x, info.y, info.targetWidth, info.targetHeight, null);
|
||||
return;
|
||||
}
|
||||
|
||||
BufferedImage tempImage = new BufferedImage(tempDestWidth, tempDestHeight, BufferedImage.TYPE_INT_RGB);
|
||||
Graphics2D g2temp = tempImage.createGraphics();
|
||||
switch (multiPassType) {
|
||||
case nearestNeighbor:
|
||||
g2temp.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR);
|
||||
break;
|
||||
case bilinear:
|
||||
g2temp.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
|
||||
break;
|
||||
case bicubic:
|
||||
g2temp.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC);
|
||||
break;
|
||||
}
|
||||
// Render first pass from image to temp.
|
||||
g2temp.drawImage(srcImage, 0, 0, tempDestWidth, tempDestHeight, null);
|
||||
// Render passes between the first and last pass.
|
||||
int tempSrcWidth = tempDestWidth;
|
||||
int tempSrcHeight = tempDestHeight;
|
||||
while (true) {
|
||||
if (tempDestWidth > info.targetWidth) {
|
||||
tempDestWidth = tempDestWidth / 2;
|
||||
if (tempDestWidth < info.targetWidth) {
|
||||
tempDestWidth = info.targetWidth;
|
||||
}
|
||||
}
|
||||
|
||||
if (tempDestHeight > info.targetHeight) {
|
||||
tempDestHeight = tempDestHeight / 2;
|
||||
if (tempDestHeight < info.targetHeight) {
|
||||
tempDestHeight = info.targetHeight;
|
||||
}
|
||||
}
|
||||
|
||||
if (tempDestWidth == info.targetWidth && tempDestHeight == info.targetHeight) {
|
||||
break;
|
||||
}
|
||||
|
||||
g2temp.drawImage(tempImage, 0, 0, tempDestWidth, tempDestHeight, 0, 0, tempSrcWidth, tempSrcHeight, null);
|
||||
|
||||
tempSrcWidth = tempDestWidth;
|
||||
tempSrcHeight = tempDestHeight;
|
||||
}
|
||||
g2temp.dispose();
|
||||
// Render last pass from temp to panel surface.
|
||||
g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, hint);
|
||||
g2.drawImage(tempImage, info.x, info.y, info.x + info.targetWidth, info.y + info.targetHeight, 0, 0, tempSrcWidth,
|
||||
tempSrcHeight, null);
|
||||
}
|
||||
|
||||
public Image getSrcImage() {
|
||||
public BufferedImage getSrcImage() {
|
||||
return srcImage;
|
||||
}
|
||||
|
||||
private static class ScalingInfo {
|
||||
public int targetWidth;
|
||||
public int targetHeight;
|
||||
public int srcWidth;
|
||||
public int srcHeight;
|
||||
public int x;
|
||||
public int y;
|
||||
}
|
||||
|
||||
public static enum MultipassType {
|
||||
none, nearestNeighbor, bilinear, bicubic
|
||||
}
|
||||
|
||||
public static enum ScalingType {
|
||||
nearestNeighbor, replicate, bilinear, bicubic, areaAveraging
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue