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 17package com.android.bitmap.util; 18 19import android.graphics.Rect; 20 21public abstract class BitmapUtils { 22 23 /** 24 * Calculate a rectangle for the given input and output parameters. The output 25 * 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 horizSliceFrac horizontal slice fraction determines the horizontal 38 * center point for the crop rect. Range is from [0.0, 1.0]. To 39 * perform a horizontally centered crop, use 0.5. 40 * @param vertSliceFrac vertical slice fraction determines the vertical 41 * center point for the crop rect. Range is from [0.0, 1.0]. To 42 * perform a vertically centered crop, use 0.5. Otherwise, see 43 * absoluteFrac. 44 * @param absoluteFrac determines how the vertSliceFrac affects the vertical 45 * center point. If this parameter is true, the vertical center 46 * of the resulting output rectangle will be exactly 47 * [vertSliceFrac * srcH], with care taken to keep the bounds 48 * within the source rectangle. If this parameter is false, the 49 * vertical center will be calculated so that the values of 50 * vertSliceFrac from 0.0 to 1.0 will linearly cover the entirety 51 * of the source rectangle. 52 * @param verticalMultiplier an optional multiplier that will alter the 53 * output Rect's aspect ratio to be this much taller in the event 54 * that y is the limiting dimension 55 * @param outRect a Rect to write the resulting crop coordinates into 56 */ 57 public static void calculateCroppedSrcRect(final int srcW, final int srcH, final int dstW, 58 final int dstH, final int dstSliceH, int sampleSize, final float horizSliceFrac, 59 final float vertSliceFrac, final boolean absoluteFrac, final float verticalMultiplier, 60 final Rect outRect) { 61 if (sampleSize < 1) { 62 sampleSize = 1; 63 } 64 final float regularScale; 65 final float wScale = (float) srcW / dstW; 66 final float hScale = (float) srcH / dstH; 67 if (hScale < wScale) { 68 regularScale = hScale / verticalMultiplier; 69 } else { 70 regularScale = wScale; 71 } 72 73 final float scale = Math.min(sampleSize, regularScale); 74 75 final int srcCroppedW = Math.round(dstW * scale); 76 final int srcCroppedH = Math.round(dstH * scale); 77 final int srcCroppedSliceH = Math.round(dstSliceH * scale); 78 final int srcHalfSliceH = Math.min(srcCroppedSliceH, srcH) / 2; 79 80 outRect.left = (int) (horizSliceFrac * (srcW - srcCroppedW)); 81 outRect.right = outRect.left + srcCroppedW; 82 83 final int centerV; 84 if (absoluteFrac) { 85 final int minCenterV = srcHalfSliceH; 86 final int maxCenterV = srcH - srcHalfSliceH; 87 centerV = Math.max(minCenterV, Math.min(maxCenterV, Math.round(srcH * vertSliceFrac))); 88 } else { 89 centerV = Math 90 .round(Math.abs(srcH - srcCroppedSliceH) * vertSliceFrac + srcHalfSliceH); 91 } 92 93 outRect.top = centerV - srcCroppedH / 2; 94 outRect.bottom = outRect.top + srcCroppedH; 95 } 96 97 /** 98 * @param srcW 99 * @param srcH 100 * @param dstW 101 * @param dstH 102 * @param outRect 103 */ 104 public static void calculateCroppedSrcRect(int srcW, int srcH, int dstW, int dstH, 105 Rect outRect) { 106 calculateCroppedSrcRect(srcW, srcH, dstW, dstH, Integer.MAX_VALUE, outRect); 107 } 108 109 public static void calculateCroppedSrcRect(int srcW, int srcH, int dstW, int dstH, 110 int sampleSize, Rect outRect) { 111 if (sampleSize < 1) { 112 sampleSize = 1; 113 } 114 final float regularScale = Math.min( 115 (float) srcW / dstW, 116 (float) srcH / dstH); 117 118 final float scale = Math.min(sampleSize, regularScale); 119 120 final int srcCroppedW = Math.round(dstW * scale); 121 final int srcCroppedH = Math.round(dstH * scale); 122 123 outRect.left = (srcW - srcCroppedW) / 2; 124 outRect.right = outRect.left + srcCroppedW; 125 126 outRect.top = (srcH - srcCroppedH) / 2; 127 outRect.bottom = outRect.top + srcCroppedH; 128 } 129} 130