1/* 2 * Copyright (C) 2015 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 */ 16package android.support.car.ui; 17 18import android.content.res.Resources; 19import android.graphics.Bitmap; 20import android.graphics.Canvas; 21import android.graphics.ColorFilter; 22import android.graphics.PixelFormat; 23import android.graphics.Rect; 24import android.graphics.drawable.Drawable; 25import android.support.annotation.NonNull; 26import android.support.v4.graphics.drawable.RoundedBitmapDrawable; 27import android.support.v4.graphics.drawable.RoundedBitmapDrawableFactory; 28 29 30/** 31 * A drawable for displaying a circular bitmap. This is a wrapper over RoundedBitmapDrawable, 32 * since that implementation doesn't behave quite as desired. 33 * 34 * Note that not all drawable functionality is passed to the RoundedBitmapDrawable at this 35 * time. Feel free to add more as necessary. 36 * @hide 37 */ 38public class CircleBitmapDrawable extends Drawable { 39 private final Resources mResources; 40 41 private Bitmap mBitmap; 42 private RoundedBitmapDrawable mDrawable; 43 private int mAlpha = -1; 44 private ColorFilter mCf = null; 45 46 public CircleBitmapDrawable(@NonNull Resources res, @NonNull Bitmap bitmap) { 47 mBitmap = bitmap; 48 mResources = res; 49 } 50 51 @Override 52 public void onBoundsChange(Rect bounds) { 53 super.onBoundsChange(bounds); 54 int width = bounds.right - bounds.left; 55 int height = bounds.bottom - bounds.top; 56 57 Bitmap processed = mBitmap; 58 /* if (processed.getWidth() != width || processed.getHeight() != height) { 59 processed = BitmapUtils.scaleBitmap(processed, width, height); 60 } 61 // RoundedBitmapDrawable is actually just a rounded rectangle. So it can't turn 62 // rectangular images into circles. 63 if (processed.getWidth() != processed.getHeight()) { 64 int diam = Math.min(width, height); 65 Bitmap cropped = BitmapUtils.cropBitmap(processed, diam, diam); 66 if (processed != mBitmap) { 67 processed.recycle(); 68 } 69 processed = cropped; 70 }*/ 71 mDrawable = RoundedBitmapDrawableFactory.create(mResources, processed); 72 mDrawable.setBounds(bounds); 73 mDrawable.setAntiAlias(true); 74 mDrawable.setCornerRadius(Math.min(width, height) / 2f); 75 if (mAlpha != -1) { 76 mDrawable.setAlpha(mAlpha); 77 } 78 if (mCf != null) { 79 mDrawable.setColorFilter(mCf); 80 } 81 invalidateSelf(); 82 } 83 84 @Override 85 public void draw(Canvas canvas) { 86 if (mDrawable != null) { 87 mDrawable.draw(canvas); 88 } 89 } 90 91 @Override 92 public int getOpacity() { 93 return mDrawable != null ? mDrawable.getOpacity() : PixelFormat.TRANSLUCENT; 94 } 95 96 @Override 97 public void setAlpha(int alpha) { 98 mAlpha = alpha; 99 if (mDrawable != null) { 100 mDrawable.setAlpha(alpha); 101 invalidateSelf(); 102 } 103 } 104 105 @Override 106 public void setColorFilter(ColorFilter cf) { 107 mCf = cf; 108 if (mDrawable != null) { 109 mDrawable.setColorFilter(cf); 110 invalidateSelf(); 111 } 112 } 113 114 /** 115 * Convert the drawable to a bitmap. 116 * @param size The target size of the bitmap in pixels. 117 * @return A bitmap representation of the drawable. 118 */ 119 public Bitmap toBitmap(int size) { 120 Bitmap largeIcon = Bitmap.createBitmap(size, size, Bitmap.Config.ARGB_8888); 121 Canvas canvas = new Canvas(largeIcon); 122 Rect bounds = getBounds(); 123 setBounds(0, 0, canvas.getWidth(), canvas.getHeight()); 124 draw(canvas); 125 setBounds(bounds); 126 return largeIcon; 127 } 128} 129 130