/* * Copyright (C) 2011 Cyril Mottier (http://www.cyrilmottier.com) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package greendroid.image; import android.graphics.Bitmap; import android.graphics.Bitmap.Config; import android.graphics.Canvas; import android.graphics.Matrix; import android.graphics.RectF; import android.widget.ImageView.ScaleType; /** * Scales Bitmaps according to a given width and height. The scaling method may * be one of the ScaleType values * * @author Cyril Mottier * @author kennydude */ public class ScaleImageProcessor implements ImageProcessor { private int mWidth; private int mHeight; private ScaleType mScaleType; private final Matrix mMatrix = new Matrix(); private final RectF mTempSrc = new RectF(); private final RectF mTempDst = new RectF(); /** * Create a new ScaleImageProcessor. * * @param width The width of the final surrounding box * @param height The height of the final surrounding box * @param scaleType The ScaleType method used to scale the original Bitmap */ public ScaleImageProcessor(int width, int height, ScaleType scaleType) { mWidth = width; mHeight = height; mScaleType = scaleType; } public Bitmap processImage(Bitmap bitmap) { if (bitmap == null) { return null; } mMatrix.reset(); final int bWidth = bitmap.getWidth(); final int bHeight = bitmap.getHeight(); switch (mScaleType) { case CENTER_CROP: { // Center and scale the bitmap so that it entirely fills the // given space. The bitmap ratio remains unchanged float scale; float dx = 0, dy = 0; if (bWidth * mHeight > mWidth * bHeight) { scale = (float) mHeight / (float) bHeight; dx = (mWidth - bWidth * scale) * 0.5f; } else { scale = (float) mWidth / (float) bWidth; dy = (mHeight - bHeight * scale) * 0.5f; } mMatrix.setScale(scale, scale); mMatrix.postTranslate((int) (dx + 0.5f), (int) (dy + 0.5f)); break; } case CENTER: { // Center bitmap without scaling final int dx = (int) ((mWidth - bWidth) * 0.5f + 0.5f); final int dy = (int) ((mHeight - bHeight) * 0.5f + 0.5f); mMatrix.setTranslate(dx, dy); break; } case CENTER_INSIDE: { // Center and scale the bitmap so that it entirely fits into the // given space. float scale; float dx; float dy; if (bWidth <= mWidth && bHeight <= mHeight) { scale = 1.0f; } else { scale = Math.min((float) mWidth / (float) bWidth, (float) mHeight / (float) bHeight); } dx = (int) ((mWidth - bWidth * scale) * 0.5f + 0.5f); dy = (int) ((mHeight - bHeight * scale) * 0.5f + 0.5f); mMatrix.setScale(scale, scale); mMatrix.postTranslate(dx, dy); break; } case FIT_XY: default: // Entirely fills the space without respecting bitmap's ratio. mTempSrc.set(0, 0, bWidth, bHeight); mTempDst.set(0, 0, mWidth, mHeight); mMatrix.setRectToRect(mTempSrc, mTempDst, Matrix.ScaleToFit.FILL); break; } Bitmap result = Bitmap.createBitmap(mWidth, mHeight, Config.ARGB_8888); Canvas canvas = new Canvas(result); canvas.drawBitmap(bitmap, mMatrix, null); return result; } }