1 /* 2 * Copyright (C) 2011 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.assetstudiolib; 18 19 import java.awt.AlphaComposite; 20 import java.awt.Color; 21 import java.awt.Graphics2D; 22 import java.awt.Rectangle; 23 import java.awt.image.BufferedImage; 24 import java.util.HashMap; 25 import java.util.Map; 26 27 /** 28 * A {@link GraphicGenerator} that generates Android "launcher" icons. 29 */ 30 public class LauncherIconGenerator extends GraphicGenerator { 31 private static final Rectangle IMAGE_SIZE_MDPI = new Rectangle(0, 0, 48, 48); 32 private static final Rectangle TARGET_RECT_MDPI = new Rectangle(2, 2, 44, 44); 33 34 @Override generate(GraphicGeneratorContext context, Options options)35 public BufferedImage generate(GraphicGeneratorContext context, Options options) { 36 LauncherOptions launcherOptions = (LauncherOptions) options; 37 38 String density; 39 if (launcherOptions.isWebGraphic) { 40 density = "web"; 41 } else { 42 density = launcherOptions.density.getResourceValue(); 43 } 44 String shape = launcherOptions.shape.id; 45 BufferedImage mBackImage = null; 46 BufferedImage mForeImage = null; 47 BufferedImage mMaskImage = null; 48 if (launcherOptions.shape != Shape.NONE) { 49 mBackImage = context.loadImageResource("/images/launcher_stencil/" 50 + shape + "/" + density + "/back.png"); 51 mForeImage = context.loadImageResource("/images/launcher_stencil/" 52 + shape + "/" + density + "/" + launcherOptions.style.id + ".png"); 53 mMaskImage = context.loadImageResource("/images/launcher_stencil/" 54 + shape + "/" + density + "/mask.png"); 55 } 56 57 float scaleFactor = GraphicGenerator.getMdpiScaleFactor(launcherOptions.density); 58 if (launcherOptions.isWebGraphic) { 59 // Target size for the web graphic is 512 60 scaleFactor = 512 / (float) IMAGE_SIZE_MDPI.height; 61 } 62 Rectangle imageRect = Util.scaleRectangle(IMAGE_SIZE_MDPI, scaleFactor); 63 Rectangle targetRect = Util.scaleRectangle(TARGET_RECT_MDPI, scaleFactor); 64 65 BufferedImage outImage = Util.newArgbBufferedImage(imageRect.width, imageRect.height); 66 Graphics2D g = (Graphics2D) outImage.getGraphics(); 67 if (mBackImage != null) { 68 g.drawImage(mBackImage, 0, 0, null); 69 } 70 71 BufferedImage tempImage = Util.newArgbBufferedImage(imageRect.width, imageRect.height); 72 Graphics2D g2 = (Graphics2D) tempImage.getGraphics(); 73 if (mMaskImage != null) { 74 g2.drawImage(mMaskImage, 0, 0, null); 75 g2.setComposite(AlphaComposite.SrcAtop); 76 g2.setPaint(new Color(launcherOptions.backgroundColor)); 77 g2.fillRect(0, 0, imageRect.width, imageRect.height); 78 } 79 80 if (launcherOptions.crop) { 81 Util.drawCenterCrop(g2, launcherOptions.sourceImage, targetRect); 82 } else { 83 Util.drawCenterInside(g2, launcherOptions.sourceImage, targetRect); 84 } 85 86 g.drawImage(tempImage, 0, 0, null); 87 if (mForeImage != null) { 88 g.drawImage(mForeImage, 0, 0, null); 89 } 90 91 g.dispose(); 92 g2.dispose(); 93 94 return outImage; 95 } 96 97 @Override generate(String category, Map<String, Map<String, BufferedImage>> categoryMap, GraphicGeneratorContext context, Options options, String name)98 public void generate(String category, Map<String, Map<String, BufferedImage>> categoryMap, 99 GraphicGeneratorContext context, Options options, String name) { 100 LauncherOptions launcherOptions = (LauncherOptions) options; 101 boolean generateWebImage = launcherOptions.isWebGraphic; 102 launcherOptions.isWebGraphic = false; 103 super.generate(category, categoryMap, context, options, name); 104 105 if (generateWebImage) { 106 launcherOptions.isWebGraphic = true; 107 BufferedImage image = generate(context, options); 108 if (image != null) { 109 Map<String, BufferedImage> imageMap = new HashMap<String, BufferedImage>(); 110 categoryMap.put("Web", imageMap); 111 imageMap.put(getIconPath(options, name), image); 112 } 113 } 114 } 115 116 @Override getIconPath(Options options, String name)117 protected String getIconPath(Options options, String name) { 118 if (((LauncherOptions) options).isWebGraphic) { 119 return name + "-web.png"; // Store at the root of the project 120 } 121 122 return super.getIconPath(options, name); 123 } 124 125 /** Options specific to generating launcher icons */ 126 public static class LauncherOptions extends GraphicGenerator.Options { 127 /** Background color, as an RRGGBB packed integer */ 128 public int backgroundColor = 0; 129 130 /** Whether the image should be cropped or not */ 131 public boolean crop = true; 132 133 /** The shape to use for the background */ 134 public Shape shape = Shape.SQUARE; 135 136 /** The effects to apply to the foreground */ 137 public Style style = Style.SIMPLE; 138 139 /** 140 * Whether a web graphic should be generated (will ignore normal density 141 * setting). The {@link #generate(GraphicGeneratorContext, Options)} 142 * method will use this to decide whether to generate a normal density 143 * icon or a high res web image. The 144 * {@link GraphicGenerator#generate(String, Map, GraphicGeneratorContext, Options, String)} 145 * method will use this flag to determine whether it should include a 146 * web graphic in its iteration. 147 */ 148 public boolean isWebGraphic; 149 } 150 } 151