1 /* 2 * Copyright (C) 2013 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.bitmap; 18 19 import android.graphics.Rect; 20 21 public abstract class BitmapUtils { 22 23 /** 24 * Calculate a center-crop rectangle for the given input and output 25 * parameters. The output rectangle to use is written in the given outRect. 26 * 27 * @param srcW the source width 28 * @param srcH the source height 29 * @param dstW the destination width 30 * @param dstH the destination height 31 * @param dstSliceH the height extent (in destination coordinates) to 32 * exclude when cropping. You would typically pass dstH, unless 33 * you are trying to normalize different items to the same 34 * vertical crop range. 35 * @param sampleSize a scaling factor that rect calculation will only use if 36 * it's more aggressive than regular scaling 37 * @param vertSliceFrac vertical slice fraction determines the vertical 38 * center point for the crop rect. Range is from [0.0, 1.0]. To 39 * perform a vertically centered crop, use 0.5. Otherwise, see 40 * absoluteFrac. 41 * @param absoluteFrac determines how the vertSliceFrac affects the vertical 42 * center point. If this parameter is true, the vertical center 43 * of the resulting output rectangle will be exactly 44 * [vertSliceFrac * srcH], with care taken to keep the bounds 45 * within the source rectangle. If this parameter is false, the 46 * vertical center will be calculated so that the values of 47 * vertSliceFrac from 0.0 to 1.0 will linearly cover the entirety 48 * of the source rectangle. 49 * @param verticalMultiplier an optional multiplier that will alter the 50 * output Rect's aspect ratio to be this much taller in the event 51 * that y is the limiting dimension 52 * @param outRect a Rect to write the resulting crop coordinates into 53 */ 54 public static void calculateCroppedSrcRect(final int srcW, final int srcH, final int dstW, 55 final int dstH, final int dstSliceH, int sampleSize, final float vertSliceFrac, 56 final boolean absoluteFrac, final float verticalMultiplier, final Rect outRect) { 57 if (sampleSize < 1) { 58 sampleSize = 1; 59 } 60 final float regularScale; 61 final float wScale = (float) srcW / dstW; 62 final float hScale = (float) srcH / dstH; 63 if (hScale < wScale) { 64 regularScale = hScale / verticalMultiplier; 65 } else { 66 regularScale = wScale; 67 } 68 69 final float scale = Math.min(sampleSize, regularScale); 70 71 final int srcCroppedW = Math.round(dstW * scale); 72 final int srcCroppedH = Math.round(dstH * scale); 73 final int srcCroppedSliceH = Math.round(dstSliceH * scale); 74 final int srcHalfSliceH = Math.min(srcCroppedSliceH, srcH) / 2; 75 76 outRect.left = (srcW - srcCroppedW) / 2; 77 outRect.right = outRect.left + srcCroppedW; 78 79 final int centerV; 80 if (absoluteFrac) { 81 final int minCenterV = srcHalfSliceH; 82 final int maxCenterV = srcH - srcHalfSliceH; 83 centerV = Math.max(minCenterV, Math.min(maxCenterV, Math.round(srcH * vertSliceFrac))); 84 } else { 85 centerV = Math 86 .round(Math.abs(srcH - srcCroppedSliceH) * vertSliceFrac + srcHalfSliceH); 87 } 88 89 outRect.top = centerV - srcCroppedH / 2; 90 outRect.bottom = outRect.top + srcCroppedH; 91 } 92 93 } 94