round image corners when No Border is selected

Signed-off-by: Jamin W. Collins <jamin.collins@gmail.com>
This commit is contained in:
Jamin W. Collins
2018-08-12 11:45:19 -06:00
parent 2174672511
commit 385fa74c6e

View File

@@ -17,6 +17,8 @@
*/ */
package forge; package forge;
import java.awt.*;
import java.awt.geom.RoundRectangle2D;
import java.awt.image.BufferedImage; import java.awt.image.BufferedImage;
import java.io.File; import java.io.File;
import java.util.HashSet; import java.util.HashSet;
@@ -25,6 +27,7 @@ import java.util.concurrent.ExecutionException;
import javax.imageio.ImageIO; import javax.imageio.ImageIO;
import forge.properties.ForgePreferences;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import com.google.common.cache.CacheBuilder; import com.google.common.cache.CacheBuilder;
@@ -146,6 +149,39 @@ public class ImageCache {
// Load from file and add to cache if not found in cache initially. // Load from file and add to cache if not found in cache initially.
BufferedImage original = getImage(imageKey); BufferedImage original = getImage(imageKey);
// If the user has indicated that they prefer Forge NOT render a black border, round the image corners
// to account for JPEG images that don't have a transparency.
boolean noBorder = !isPreferenceEnabled(ForgePreferences.FPref.UI_RENDER_BLACK_BORDERS);
if (original != null && noBorder) {
// use a quadratic equation to calculate the needed radius from an image dimension
int radius;
float width = original.getWidth();
String setCode = imageKey.split("/")[0].trim().toUpperCase();
if (setCode.equals("A")) { // Alpha
// radius = 100; // 745 x 1040
// radius = 68; // 488 x 680
// radius = 25; // 146 x 204
radius = (int)(-107.0 *(width * width) / 52648506.0 + 743043.0 * width / 5849834.0 + 171067480.0 / 26324253.0);
} else if (setCode.equals("ME2") || // Masters Edition II
setCode.equals("ME3") || // Masters Edition III
setCode.equals("ME4") || // Masters Edition IV
setCode.equals("TD0") // Commander
) {
// radius = 77; // 745 x 1040
// radius = 52; // 488 x 680
// radius = 19; // 146 x 204
radius = (int)(23.0 * (width * width) / 17549502.0 + 559597.0 * width /5849834.0 + 43923392.0 / 8774751.0);
} else {
// radius = 65; // 745 x 1040
// radius = 45; // 488 x 680
// radius = 15; // 146 x 204
radius = (int)(-145.0 * (width * width) / 8774751.0 + 287215.0 * width / 2924917.0 + 8911915.0 / 8774751.0);
}
//System.out.println(setCode + " - " + original.getWidth() + " - " + radius);
original = makeRoundedCorner(original, radius);
}
// No image file exists for the given key so optionally associate with // No image file exists for the given key so optionally associate with
// a default "not available" image, however do not add it to the cache, // a default "not available" image, however do not add it to the cache,
// as otherwise it's problematic to update if the real image gets fetched. // as otherwise it's problematic to update if the real image gets fetched.
@@ -229,4 +265,32 @@ public class ImageCache {
return null; return null;
} }
} }
private static boolean isPreferenceEnabled(final ForgePreferences.FPref preferenceName) {
return FModel.getPreferences().getPrefBoolean(preferenceName);
}
public static BufferedImage makeRoundedCorner(BufferedImage image, int cornerRadius) {
int w = image.getWidth();
int h = image.getHeight();
BufferedImage output = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
Graphics2D g2 = output.createGraphics();
// so instead fake soft-clipping by first drawing the desired clip shape
// in fully opaque black with antialiasing enabled...
g2.setComposite(AlphaComposite.Src);
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2.setColor(Color.BLACK);
g2.fill(new RoundRectangle2D.Float(0, 0, w, h, cornerRadius, cornerRadius));
// ... then compositing the image on top,
// using the black shape from above as alpha source
g2.setComposite(AlphaComposite.SrcAtop);
g2.drawImage(image, 0, 0, null);
g2.dispose();
return output;
}
} }