1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123
| public static Bitmap createBitmap(@NonNull Bitmap source, int x, int y, int width, int height, @Nullable Matrix m, boolean filter) {
checkXYSign(x, y); checkWidthHeight(width, height); if (x + width > source.getWidth()) { throw new IllegalArgumentException("x + width must be <= bitmap.width()"); } if (y + height > source.getHeight()) { throw new IllegalArgumentException("y + height must be <= bitmap.height()"); } if (source.isRecycled()) { throw new IllegalArgumentException("cannot use a recycled source in createBitmap"); }
if (!source.isMutable() && x == 0 && y == 0 && width == source.getWidth() && height == source.getHeight() && (m == null || m.isIdentity())) { return source; }
boolean isHardware = source.getConfig() == Config.HARDWARE; if (isHardware) { source.noteHardwareBitmapSlowCall(); source = nativeCopyPreserveInternalConfig(source.mNativePtr); }
int neww = width; int newh = height; Bitmap bitmap; Paint paint;
Rect srcR = new Rect(x, y, x + width, y + height); RectF dstR = new RectF(0, 0, width, height); RectF deviceR = new RectF();
Config newConfig = Config.ARGB_8888; final Config config = source.getConfig(); if (config != null) { switch (config) { case RGB_565: newConfig = Config.RGB_565; break; case ALPHA_8: newConfig = Config.ALPHA_8; break; case RGBA_F16: newConfig = Config.RGBA_F16; break; case ARGB_4444: case ARGB_8888: default: newConfig = Config.ARGB_8888; break; } }
ColorSpace cs = source.getColorSpace();
if (m == null || m.isIdentity()) { bitmap = createBitmap(null, neww, newh, newConfig, source.hasAlpha(), cs); paint = null; } else { final boolean transformed = !m.rectStaysRect();
m.mapRect(deviceR, dstR);
neww = Math.round(deviceR.width()); newh = Math.round(deviceR.height());
Config transformedConfig = newConfig; if (transformed) { if (transformedConfig != Config.ARGB_8888 && transformedConfig != Config.RGBA_F16) { transformedConfig = Config.ARGB_8888; if (cs == null) { cs = Color
Space.get(ColorSpace.Named.SRGB); } } }
bitmap = createBitmap(null, neww, newh, transformedConfig, transformed || source.hasAlpha(), cs);
paint = new Paint(); paint.setFilterBitmap(filter); if (transformed) { paint.setAntiAlias(true); } }
bitmap.mDensity = source.mDensity; bitmap.setHasAlpha(source.hasAlpha()); bitmap.setPremultiplied(source.mRequestPremultiplied);
Canvas canvas = new Canvas(bitmap); canvas.translate(-deviceR.left, -deviceR.top); canvas.concat(m); canvas.drawBitmap(source, srcR, dstR, paint); canvas.setBitmap(null);
if (isHardware) { return bitmap.copy(Config.HARDWARE, false); }
return bitmap; }
|