1 /* 2 * Copyright (C) 2008 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 android.graphics; 18 19 20 import java.awt.image.BufferedImage; 21 import java.io.File; 22 import java.io.IOException; 23 24 import javax.imageio.ImageIO; 25 26 public final class Bitmap extends _Original_Bitmap { 27 28 private BufferedImage mImage; 29 Bitmap(File input)30 public Bitmap(File input) throws IOException { 31 super(1, true, null, -1); 32 33 mImage = ImageIO.read(input); 34 } 35 Bitmap(BufferedImage image)36 Bitmap(BufferedImage image) { 37 super(1, true, null, -1); 38 mImage = image; 39 } 40 getImage()41 public BufferedImage getImage() { 42 return mImage; 43 } 44 45 // ----- overriden methods 46 47 public enum Config { 48 // these native values must match up with the enum in SkBitmap.h 49 ALPHA_8 (2), 50 RGB_565 (4), 51 ARGB_4444 (5), 52 ARGB_8888 (6); 53 Config(int ni)54 Config(int ni) { 55 this.nativeInt = ni; 56 } 57 final int nativeInt; 58 nativeToConfig(int ni)59 /* package */ static Config nativeToConfig(int ni) { 60 return sConfigs[ni]; 61 } 62 63 private static Config sConfigs[] = { 64 null, null, ALPHA_8, null, RGB_565, ARGB_4444, ARGB_8888 65 }; 66 } 67 68 @Override getWidth()69 public int getWidth() { 70 return mImage.getWidth(); 71 } 72 73 @Override getHeight()74 public int getHeight() { 75 return mImage.getHeight(); 76 } 77 78 /** 79 * Returns an immutable bitmap from the source bitmap. The new bitmap may 80 * be the same object as source, or a copy may have been made. 81 */ createBitmap(Bitmap src)82 public static Bitmap createBitmap(Bitmap src) { 83 return createBitmap(src, 0, 0, src.getWidth(), src.getHeight(), null, false); 84 } 85 86 /** 87 * Returns an immutable bitmap from the specified subset of the source 88 * bitmap. The new bitmap may be the same object as source, or a copy may 89 * have been made. 90 * 91 * @param source The bitmap we are subsetting 92 * @param x The x coordinate of the first pixel in source 93 * @param y The y coordinate of the first pixel in source 94 * @param width The number of pixels in each row 95 * @param height The number of rows 96 */ createBitmap(Bitmap source, int x, int y, int width, int height)97 public static Bitmap createBitmap(Bitmap source, int x, int y, 98 int width, int height) { 99 return new Bitmap(source.mImage.getSubimage(x, y, width, height)); 100 } 101 102 /** 103 * Returns an immutable bitmap from subset of the source bitmap, 104 * transformed by the optional matrix. 105 * 106 * @param source The bitmap we are subsetting 107 * @param x The x coordinate of the first pixel in source 108 * @param y The y coordinate of the first pixel in source 109 * @param width The number of pixels in each row 110 * @param height The number of rows 111 * @param m Option matrix to be applied to the pixels 112 * @param filter true if the source should be filtered. 113 * Only applies if the matrix contains more than just 114 * translation. 115 * @return A bitmap that represents the specified subset of source 116 * @throws IllegalArgumentException if the x, y, width, height values are 117 * outside of the dimensions of the source bitmap. 118 */ createBitmap(Bitmap source, int x, int y, int width, int height, Matrix m, boolean filter)119 public static Bitmap createBitmap(Bitmap source, int x, int y, int width, 120 int height, Matrix m, boolean filter) { 121 checkXYSign(x, y); 122 checkWidthHeight(width, height); 123 if (x + width > source.getWidth()) { 124 throw new IllegalArgumentException( 125 "x + width must be <= bitmap.width()"); 126 } 127 if (y + height > source.getHeight()) { 128 throw new IllegalArgumentException( 129 "y + height must be <= bitmap.height()"); 130 } 131 132 // check if we can just return our argument unchanged 133 if (!source.isMutable() && x == 0 && y == 0 134 && width == source.getWidth() && height == source.getHeight() 135 && (m == null || m.isIdentity())) { 136 return source; 137 } 138 139 if (m == null || m.isIdentity()) { 140 return new Bitmap(source.mImage.getSubimage(x, y, width, height)); 141 } 142 143 int neww = width; 144 int newh = height; 145 Paint paint; 146 147 Rect srcR = new Rect(x, y, x + width, y + height); 148 RectF dstR = new RectF(0, 0, width, height); 149 150 /* the dst should have alpha if the src does, or if our matrix 151 doesn't preserve rectness 152 */ 153 boolean hasAlpha = source.hasAlpha() || !m.rectStaysRect(); 154 RectF deviceR = new RectF(); 155 m.mapRect(deviceR, dstR); 156 neww = Math.round(deviceR.width()); 157 newh = Math.round(deviceR.height()); 158 159 Canvas canvas = new Canvas(neww, newh); 160 161 canvas.translate(-deviceR.left, -deviceR.top); 162 canvas.concat(m); 163 paint = new Paint(); 164 paint.setFilterBitmap(filter); 165 if (!m.rectStaysRect()) { 166 paint.setAntiAlias(true); 167 } 168 169 canvas.drawBitmap(source, srcR, dstR, paint); 170 171 return new Bitmap(canvas.getImage()); 172 } 173 174 /** 175 * Returns a mutable bitmap with the specified width and height. 176 * 177 * @param width The width of the bitmap 178 * @param height The height of the bitmap 179 * @param config The bitmap config to create. 180 * @throws IllegalArgumentException if the width or height are <= 0 181 */ createBitmap(int width, int height, Config config)182 public static Bitmap createBitmap(int width, int height, Config config) { 183 return new Bitmap(new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB)); 184 } 185 186 /** 187 * Returns a immutable bitmap with the specified width and height, with each 188 * pixel value set to the corresponding value in the colors array. 189 * 190 * @param colors Array of {@link Color} used to initialize the pixels. 191 * @param offset Number of values to skip before the first color in the 192 * array of colors. 193 * @param stride Number of colors in the array between rows (must be >= 194 * width or <= -width). 195 * @param width The width of the bitmap 196 * @param height The height of the bitmap 197 * @param config The bitmap config to create. If the config does not 198 * support per-pixel alpha (e.g. RGB_565), then the alpha 199 * bytes in the colors[] will be ignored (assumed to be FF) 200 * @throws IllegalArgumentException if the width or height are <= 0, or if 201 * the color array's length is less than the number of pixels. 202 */ createBitmap(int colors[], int offset, int stride, int width, int height, Config config)203 public static Bitmap createBitmap(int colors[], int offset, int stride, 204 int width, int height, Config config) { 205 checkWidthHeight(width, height); 206 if (Math.abs(stride) < width) { 207 throw new IllegalArgumentException("abs(stride) must be >= width"); 208 } 209 int lastScanline = offset + (height - 1) * stride; 210 int length = colors.length; 211 if (offset < 0 || (offset + width > length) 212 || lastScanline < 0 213 || (lastScanline + width > length)) { 214 throw new ArrayIndexOutOfBoundsException(); 215 } 216 217 // TODO: create an immutable bitmap... 218 throw new UnsupportedOperationException(); 219 } 220 221 /** 222 * Returns a immutable bitmap with the specified width and height, with each 223 * pixel value set to the corresponding value in the colors array. 224 * 225 * @param colors Array of {@link Color} used to initialize the pixels. 226 * This array must be at least as large as width * height. 227 * @param width The width of the bitmap 228 * @param height The height of the bitmap 229 * @param config The bitmap config to create. If the config does not 230 * support per-pixel alpha (e.g. RGB_565), then the alpha 231 * bytes in the colors[] will be ignored (assumed to be FF) 232 * @throws IllegalArgumentException if the width or height are <= 0, or if 233 * the color array's length is less than the number of pixels. 234 */ createBitmap(int colors[], int width, int height, Config config)235 public static Bitmap createBitmap(int colors[], int width, int height, 236 Config config) { 237 return createBitmap(colors, 0, width, width, height, config); 238 } 239 240 } 241