this repo has no description
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

resize thumbnails and handle other resolutions in AssetHandle

+84 -81
+1 -1
src/main/java/app/pane/AssetsPanel.java
··· 259 259 @Override 260 260 protected Image doInBackground() 261 261 { 262 - return asset.loadThumbnail(); 262 + return asset.getThumbnail(); 263 263 } 264 264 265 265 @Override
+61 -14
src/main/java/assets/AssetHandle.java
··· 1 1 package assets; 2 2 3 + import java.awt.Graphics2D; 3 4 import java.awt.Image; 5 + import java.awt.RenderingHints; 6 + import java.awt.image.BaseMultiResolutionImage; 7 + import java.awt.image.BufferedImage; 4 8 import java.io.File; 5 9 6 10 import assets.ui.BackgroundAsset; ··· 9 13 10 14 public class AssetHandle extends File 11 15 { 16 + public static final int THUMBNAIL_SIZE = 80 * 2; 17 + 12 18 public final File assetDir; 13 19 public final String assetPath; // relative path from assetDir 20 + 21 + private Image cachedThumbnail; 22 + private boolean thumbnailLoaded; 14 23 15 24 public AssetHandle(AssetHandle other) 16 25 { ··· 25 34 assetPath = path.replaceAll("\\\\", "/"); // resolve all paths with '/' as separator 26 35 } 27 36 28 - public String getAssetName() { 37 + public String getAssetName() 38 + { 29 39 int slash = assetPath.lastIndexOf('/'); 30 - if (slash >= 0) { 40 + if (slash >= 0) 31 41 return assetPath.substring(slash + 1); 32 - } else { 42 + else 33 43 return assetPath; 34 - } 35 44 } 36 45 37 - public String getAssetDescription() { 46 + public String getAssetDescription() 47 + { 38 48 return null; 39 49 } 40 50 41 - /** 42 - * Loads a thumbnail image for this asset. 43 - * Returns null if no thumbnail is available. 44 - */ 45 - public Image loadThumbnail() { 51 + /** Override in subclasses to provide a high-resolution thumbnail image. */ 52 + protected Image loadThumbnail() 53 + { 46 54 return null; 47 55 } 48 56 49 - /** 50 - * Upgrades a plain AssetHandle to a typed subclass based on file extension. 51 - * Returns null if the file doesn't match any known asset type. 52 - */ 57 + /** Returns a cached multi-resolution thumbnail, downsized from loadThumbnail. */ 58 + public final Image getThumbnail() 59 + { 60 + if (!thumbnailLoaded) { 61 + thumbnailLoaded = true; 62 + Image raw = loadThumbnail(); 63 + if (raw != null) 64 + cachedThumbnail = createMultiResThumbnail(raw); 65 + } 66 + return cachedThumbnail; 67 + } 68 + 69 + private static Image createMultiResThumbnail(Image src) 70 + { 71 + var img1x = resizeImage(src, THUMBNAIL_SIZE / 2); 72 + var img2x = resizeImage(src, THUMBNAIL_SIZE); 73 + return new BaseMultiResolutionImage(img1x, img2x); 74 + } 75 + 76 + private static BufferedImage resizeImage(Image src, int targetSize) 77 + { 78 + int srcW = src.getWidth(null); 79 + int srcH = src.getHeight(null); 80 + float srcRatio = (float) srcW / srcH; 81 + int w, h; 82 + if (srcRatio >= 1f) { 83 + w = targetSize; 84 + h = Math.max(1, Math.round(targetSize / srcRatio)); 85 + } 86 + else { 87 + h = targetSize; 88 + w = Math.max(1, Math.round(targetSize * srcRatio)); 89 + } 90 + 91 + var bi = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB); 92 + Graphics2D g = bi.createGraphics(); 93 + g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR); 94 + g.drawImage(src, 0, 0, w, h, null); 95 + g.dispose(); 96 + return bi; 97 + } 98 + 99 + /** Upgrades a plain AssetHandle to a typed subclass based on file extension. */ 53 100 public static AssetHandle upgrade(AssetHandle handle) 54 101 { 55 102 String name = handle.getAssetName();
+2 -19
src/main/java/assets/ui/BackgroundAsset.java
··· 1 1 package assets.ui; 2 2 3 - import java.awt.Graphics2D; 4 3 import java.awt.Image; 5 - import java.awt.RenderingHints; 6 4 import java.awt.image.BufferedImage; 7 5 import java.io.IOException; 8 6 ··· 13 11 public class BackgroundAsset extends AssetHandle 14 12 { 15 13 public BufferedImage bimg; 16 - public BufferedImage thumbnail; 17 14 18 15 public BackgroundAsset(AssetHandle asset) 19 16 { ··· 21 18 22 19 try { 23 20 bimg = ImageIO.read(asset); 24 - thumbnail = resizeImage(bimg, 64); 25 21 } 26 22 catch (IOException e) { 27 23 bimg = null; ··· 29 25 } 30 26 31 27 @Override 32 - public Image loadThumbnail() 28 + protected Image loadThumbnail() 33 29 { 34 - return thumbnail; 35 - } 36 - 37 - private static BufferedImage resizeImage(BufferedImage src, int targetHeight) 38 - { 39 - float ratio = ((float) src.getHeight() / (float) src.getWidth()); 40 - int targetWidth = Math.round(targetHeight / ratio); 41 - 42 - BufferedImage bi = new BufferedImage(targetWidth, targetHeight, BufferedImage.TYPE_INT_RGB); 43 - Graphics2D g2d = bi.createGraphics(); 44 - g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR); 45 - g2d.drawImage(src, 0, 0, targetWidth, targetHeight, null); 46 - g2d.dispose(); 47 - return bi; 30 + return bimg; 48 31 } 49 32 }
+1 -1
src/main/java/assets/ui/BackgroundAssetCellRenderer.java
··· 52 52 String assetDirName = bg.assetDir.getName(); 53 53 String mapFileName = FilenameUtils.getBaseName(bg.assetPath); 54 54 nameLabel.setText(assetDirName + " / " + mapFileName); 55 - previewPanel.setImage(bg.thumbnail); 55 + previewPanel.setImage(bg.bimg); 56 56 } 57 57 else { 58 58 nameLabel.setText("none");
+5 -23
src/main/java/assets/ui/MapAsset.java
··· 3 3 import static app.Directories.PROJ_THUMBNAIL; 4 4 5 5 import java.awt.Image; 6 - import java.awt.image.BaseMultiResolutionImage; 7 6 import java.io.BufferedReader; 8 7 import java.io.File; 9 8 import java.io.FileReader; 10 9 import java.io.IOException; 11 - import java.util.ArrayList; 12 10 import java.util.regex.Matcher; 13 11 import java.util.regex.Pattern; 14 12 ··· 86 84 } 87 85 88 86 @Override 89 - public Image loadThumbnail() 87 + protected Image loadThumbnail() 90 88 { 91 - var variants = new ArrayList<Image>(); 92 - 93 89 File thumbFile = new File(PROJ_THUMBNAIL + assetPath + ".png"); 94 90 if (thumbFile.exists()) { 95 91 try { 96 - variants.add(ImageIO.read(thumbFile)); 97 - } 98 - catch (IOException e) {} 99 - } 100 - 101 - File thumb2xFile = new File(PROJ_THUMBNAIL + assetPath + "@2x.png"); 102 - if (thumb2xFile.exists()) { 103 - try { 104 - variants.add(ImageIO.read(thumb2xFile)); 92 + return ImageIO.read(thumbFile); 105 93 } 106 94 catch (IOException e) {} 107 95 } 108 96 109 - if (variants.isEmpty()) 110 - return null; 111 - 112 - return new BaseMultiResolutionImage(variants.toArray(new Image[0])); 97 + return null; 113 98 } 114 99 115 - public static final int THUMBNAIL_SIZE = 80; 116 - 117 100 /** 118 101 * Generates thumbnails for all maps that don't already have one. 119 102 * Creates a MapEditor instance, so must not be called while one is open. ··· 125 108 try { 126 109 for (AssetHandle asset : AssetManager.getMapSources()) { 127 110 File thumbFile = new File(PROJ_THUMBNAIL + asset.assetPath + ".png"); 128 - File thumb2xFile = new File(PROJ_THUMBNAIL + asset.assetPath + "@2x.png"); 129 - if (thumbFile.exists() && thumb2xFile.exists()) 111 + if (thumbFile.exists()) 130 112 continue; 131 113 Logger.log("Capturing thumbnail for " + asset.assetPath + "...", Priority.MILESTONE); 132 114 if (editor == null) 133 115 editor = new MapEditor(false); 134 - editor.generateThumbnail(asset, thumbFile, thumb2xFile, THUMBNAIL_SIZE); 116 + editor.generateThumbnail(asset, thumbFile, THUMBNAIL_SIZE); 135 117 } 136 118 } 137 119 catch (Exception e) {
+14 -23
src/main/java/game/map/editor/MapEditor.java
··· 737 737 738 738 private boolean thumbnailInitialized = false; 739 739 740 - /** Renders a thumbnail at 4x resolution and saves both the 2x and downsampled 1x images. */ 741 - public void generateThumbnail(File mapFile, File thumbFile1x, File thumbFile2x, int size) 740 + /** Renders a thumbnail at 2x resolution and downsamples to the given size. */ 741 + public void generateThumbnail(File mapFile, File thumbFile, int size) 742 742 { 743 743 Map newMap = Map.loadMap(mapFile); 744 744 if (newMap == null) 745 745 return; 746 746 747 - int renderSize = size * 4; 747 + int renderSize = size * 2; 748 748 thumbnailMode = true; 749 749 thumbnailSize = renderSize; 750 750 openMap(newMap, true); ··· 823 823 glCanvas.render(); 824 824 } 825 825 826 - renderThumbnail(thumbFile1x, thumbFile2x, size); 826 + renderThumbnail(thumbFile, size); 827 827 } 828 828 829 829 public void shutdownThumbnail() ··· 3670 3670 thumbnailMode = true; 3671 3671 } 3672 3672 3673 - private void renderThumbnail(File thumbFile1x, File thumbFile2x, int size) 3673 + private void renderThumbnail(File thumbFile, int size) 3674 3674 { 3675 3675 runInContext(() -> { 3676 3676 glBindFramebuffer(GL_READ_FRAMEBUFFER, perspectiveView.getSceneFrameBuffer()); ··· 3681 3681 glReadPixels(0, 0, renderSize, renderSize, GL11.GL_RGBA, GL11.GL_UNSIGNED_BYTE, buffer); 3682 3682 glBindFramebuffer(GL_READ_FRAMEBUFFER, 0); 3683 3683 3684 - var image4x = new BufferedImage(renderSize, renderSize, BufferedImage.TYPE_INT_ARGB); 3684 + var renderImage = new BufferedImage(renderSize, renderSize, BufferedImage.TYPE_INT_ARGB); 3685 3685 for (int x = 0; x < renderSize; x++) { 3686 3686 for (int y = 0; y < renderSize; y++) { 3687 3687 int i = (x + (renderSize * y)) * bpp; ··· 3689 3689 int g = buffer.get(i + 1) & 0xFF; 3690 3690 int b = buffer.get(i + 2) & 0xFF; 3691 3691 int a = buffer.get(i + 3) & 0xFF; 3692 - image4x.setRGB(x, renderSize - (y + 1), (a << 24) | (r << 16) | (g << 8) | b); 3692 + renderImage.setRGB(x, renderSize - (y + 1), (a << 24) | (r << 16) | (g << 8) | b); 3693 3693 } 3694 3694 } 3695 3695 3696 - // Downsample to 2x and 1x with bilinear filtering 3697 - int size2x = size * 2; 3698 - var image2x = new BufferedImage(size2x, size2x, BufferedImage.TYPE_INT_ARGB); 3699 - Graphics2D g2 = image2x.createGraphics(); 3700 - g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR); 3701 - g2.drawImage(image4x, 0, 0, size2x, size2x, null); 3702 - g2.dispose(); 3703 - 3704 - var image1x = new BufferedImage(size, size, BufferedImage.TYPE_INT_ARGB); 3705 - Graphics2D g1 = image1x.createGraphics(); 3706 - g1.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR); 3707 - g1.drawImage(image2x, 0, 0, size, size, null); 3708 - g1.dispose(); 3696 + var image = new BufferedImage(size, size, BufferedImage.TYPE_INT_ARGB); 3697 + Graphics2D g = image.createGraphics(); 3698 + g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR); 3699 + g.drawImage(renderImage, 0, 0, size, size, null); 3700 + g.dispose(); 3709 3701 3710 3702 try { 3711 - FileUtils.forceMkdirParent(thumbFile1x); 3712 - ImageIO.write(image1x, "PNG", thumbFile1x); 3713 - ImageIO.write(image2x, "PNG", thumbFile2x); 3703 + FileUtils.forceMkdirParent(thumbFile); 3704 + ImageIO.write(image, "PNG", thumbFile); 3714 3705 } 3715 3706 catch (IOException e) { 3716 3707 Logger.printStackTrace(e);