193a35b93dc582e38ff8ee5979754a16b4bf4da0cSam Blitzstein/* 293a35b93dc582e38ff8ee5979754a16b4bf4da0cSam Blitzstein * Copyright (C) 2013 The Android Open Source Project 393a35b93dc582e38ff8ee5979754a16b4bf4da0cSam Blitzstein * 493a35b93dc582e38ff8ee5979754a16b4bf4da0cSam Blitzstein * Licensed under the Apache License, Version 2.0 (the "License"); 593a35b93dc582e38ff8ee5979754a16b4bf4da0cSam Blitzstein * you may not use this file except in compliance with the License. 693a35b93dc582e38ff8ee5979754a16b4bf4da0cSam Blitzstein * You may obtain a copy of the License at 793a35b93dc582e38ff8ee5979754a16b4bf4da0cSam Blitzstein * 893a35b93dc582e38ff8ee5979754a16b4bf4da0cSam Blitzstein * http://www.apache.org/licenses/LICENSE-2.0 993a35b93dc582e38ff8ee5979754a16b4bf4da0cSam Blitzstein * 1093a35b93dc582e38ff8ee5979754a16b4bf4da0cSam Blitzstein * Unless required by applicable law or agreed to in writing, software 1193a35b93dc582e38ff8ee5979754a16b4bf4da0cSam Blitzstein * distributed under the License is distributed on an "AS IS" BASIS, 1293a35b93dc582e38ff8ee5979754a16b4bf4da0cSam Blitzstein * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1393a35b93dc582e38ff8ee5979754a16b4bf4da0cSam Blitzstein * See the License for the specific language governing permissions and 1493a35b93dc582e38ff8ee5979754a16b4bf4da0cSam Blitzstein * limitations under the License. 1593a35b93dc582e38ff8ee5979754a16b4bf4da0cSam Blitzstein */ 1693a35b93dc582e38ff8ee5979754a16b4bf4da0cSam Blitzstein 1793a35b93dc582e38ff8ee5979754a16b4bf4da0cSam Blitzsteinpackage com.android.bitmap.util; 1893a35b93dc582e38ff8ee5979754a16b4bf4da0cSam Blitzstein 1993a35b93dc582e38ff8ee5979754a16b4bf4da0cSam Blitzsteinimport android.graphics.Rect; 2093a35b93dc582e38ff8ee5979754a16b4bf4da0cSam Blitzstein 2193a35b93dc582e38ff8ee5979754a16b4bf4da0cSam Blitzsteinpublic abstract class BitmapUtils { 2293a35b93dc582e38ff8ee5979754a16b4bf4da0cSam Blitzstein 2393a35b93dc582e38ff8ee5979754a16b4bf4da0cSam Blitzstein /** 243a79e2002f9f6114b549c4bc2cc08bb10e75a4d2James Kung * Calculate a rectangle for the given input and output parameters. The output 253a79e2002f9f6114b549c4bc2cc08bb10e75a4d2James Kung * rectangle to use is written in the given outRect. 2693a35b93dc582e38ff8ee5979754a16b4bf4da0cSam Blitzstein * 2793a35b93dc582e38ff8ee5979754a16b4bf4da0cSam Blitzstein * @param srcW the source width 2893a35b93dc582e38ff8ee5979754a16b4bf4da0cSam Blitzstein * @param srcH the source height 2993a35b93dc582e38ff8ee5979754a16b4bf4da0cSam Blitzstein * @param dstW the destination width 3093a35b93dc582e38ff8ee5979754a16b4bf4da0cSam Blitzstein * @param dstH the destination height 3193a35b93dc582e38ff8ee5979754a16b4bf4da0cSam Blitzstein * @param dstSliceH the height extent (in destination coordinates) to 3293a35b93dc582e38ff8ee5979754a16b4bf4da0cSam Blitzstein * exclude when cropping. You would typically pass dstH, unless 3393a35b93dc582e38ff8ee5979754a16b4bf4da0cSam Blitzstein * you are trying to normalize different items to the same 3493a35b93dc582e38ff8ee5979754a16b4bf4da0cSam Blitzstein * vertical crop range. 3593a35b93dc582e38ff8ee5979754a16b4bf4da0cSam Blitzstein * @param sampleSize a scaling factor that rect calculation will only use if 3693a35b93dc582e38ff8ee5979754a16b4bf4da0cSam Blitzstein * it's more aggressive than regular scaling 373a79e2002f9f6114b549c4bc2cc08bb10e75a4d2James Kung * @param horizSliceFrac horizontal slice fraction determines the horizontal 383a79e2002f9f6114b549c4bc2cc08bb10e75a4d2James Kung * center point for the crop rect. Range is from [0.0, 1.0]. To 393a79e2002f9f6114b549c4bc2cc08bb10e75a4d2James Kung * perform a horizontally centered crop, use 0.5. 4093a35b93dc582e38ff8ee5979754a16b4bf4da0cSam Blitzstein * @param vertSliceFrac vertical slice fraction determines the vertical 4193a35b93dc582e38ff8ee5979754a16b4bf4da0cSam Blitzstein * center point for the crop rect. Range is from [0.0, 1.0]. To 4293a35b93dc582e38ff8ee5979754a16b4bf4da0cSam Blitzstein * perform a vertically centered crop, use 0.5. Otherwise, see 4393a35b93dc582e38ff8ee5979754a16b4bf4da0cSam Blitzstein * absoluteFrac. 4493a35b93dc582e38ff8ee5979754a16b4bf4da0cSam Blitzstein * @param absoluteFrac determines how the vertSliceFrac affects the vertical 4593a35b93dc582e38ff8ee5979754a16b4bf4da0cSam Blitzstein * center point. If this parameter is true, the vertical center 4693a35b93dc582e38ff8ee5979754a16b4bf4da0cSam Blitzstein * of the resulting output rectangle will be exactly 4793a35b93dc582e38ff8ee5979754a16b4bf4da0cSam Blitzstein * [vertSliceFrac * srcH], with care taken to keep the bounds 4893a35b93dc582e38ff8ee5979754a16b4bf4da0cSam Blitzstein * within the source rectangle. If this parameter is false, the 4993a35b93dc582e38ff8ee5979754a16b4bf4da0cSam Blitzstein * vertical center will be calculated so that the values of 5093a35b93dc582e38ff8ee5979754a16b4bf4da0cSam Blitzstein * vertSliceFrac from 0.0 to 1.0 will linearly cover the entirety 5193a35b93dc582e38ff8ee5979754a16b4bf4da0cSam Blitzstein * of the source rectangle. 5293a35b93dc582e38ff8ee5979754a16b4bf4da0cSam Blitzstein * @param verticalMultiplier an optional multiplier that will alter the 5393a35b93dc582e38ff8ee5979754a16b4bf4da0cSam Blitzstein * output Rect's aspect ratio to be this much taller in the event 5493a35b93dc582e38ff8ee5979754a16b4bf4da0cSam Blitzstein * that y is the limiting dimension 5593a35b93dc582e38ff8ee5979754a16b4bf4da0cSam Blitzstein * @param outRect a Rect to write the resulting crop coordinates into 5693a35b93dc582e38ff8ee5979754a16b4bf4da0cSam Blitzstein */ 5793a35b93dc582e38ff8ee5979754a16b4bf4da0cSam Blitzstein public static void calculateCroppedSrcRect(final int srcW, final int srcH, final int dstW, 583a79e2002f9f6114b549c4bc2cc08bb10e75a4d2James Kung final int dstH, final int dstSliceH, int sampleSize, final float horizSliceFrac, 593a79e2002f9f6114b549c4bc2cc08bb10e75a4d2James Kung final float vertSliceFrac, final boolean absoluteFrac, final float verticalMultiplier, 603a79e2002f9f6114b549c4bc2cc08bb10e75a4d2James Kung final Rect outRect) { 6193a35b93dc582e38ff8ee5979754a16b4bf4da0cSam Blitzstein if (sampleSize < 1) { 6293a35b93dc582e38ff8ee5979754a16b4bf4da0cSam Blitzstein sampleSize = 1; 6393a35b93dc582e38ff8ee5979754a16b4bf4da0cSam Blitzstein } 6493a35b93dc582e38ff8ee5979754a16b4bf4da0cSam Blitzstein final float regularScale; 6593a35b93dc582e38ff8ee5979754a16b4bf4da0cSam Blitzstein final float wScale = (float) srcW / dstW; 6693a35b93dc582e38ff8ee5979754a16b4bf4da0cSam Blitzstein final float hScale = (float) srcH / dstH; 6793a35b93dc582e38ff8ee5979754a16b4bf4da0cSam Blitzstein if (hScale < wScale) { 6893a35b93dc582e38ff8ee5979754a16b4bf4da0cSam Blitzstein regularScale = hScale / verticalMultiplier; 6993a35b93dc582e38ff8ee5979754a16b4bf4da0cSam Blitzstein } else { 7093a35b93dc582e38ff8ee5979754a16b4bf4da0cSam Blitzstein regularScale = wScale; 7193a35b93dc582e38ff8ee5979754a16b4bf4da0cSam Blitzstein } 7293a35b93dc582e38ff8ee5979754a16b4bf4da0cSam Blitzstein 7393a35b93dc582e38ff8ee5979754a16b4bf4da0cSam Blitzstein final float scale = Math.min(sampleSize, regularScale); 7493a35b93dc582e38ff8ee5979754a16b4bf4da0cSam Blitzstein 7593a35b93dc582e38ff8ee5979754a16b4bf4da0cSam Blitzstein final int srcCroppedW = Math.round(dstW * scale); 7693a35b93dc582e38ff8ee5979754a16b4bf4da0cSam Blitzstein final int srcCroppedH = Math.round(dstH * scale); 7793a35b93dc582e38ff8ee5979754a16b4bf4da0cSam Blitzstein final int srcCroppedSliceH = Math.round(dstSliceH * scale); 7893a35b93dc582e38ff8ee5979754a16b4bf4da0cSam Blitzstein final int srcHalfSliceH = Math.min(srcCroppedSliceH, srcH) / 2; 7993a35b93dc582e38ff8ee5979754a16b4bf4da0cSam Blitzstein 803a79e2002f9f6114b549c4bc2cc08bb10e75a4d2James Kung outRect.left = (int) (horizSliceFrac * (srcW - srcCroppedW)); 8193a35b93dc582e38ff8ee5979754a16b4bf4da0cSam Blitzstein outRect.right = outRect.left + srcCroppedW; 8293a35b93dc582e38ff8ee5979754a16b4bf4da0cSam Blitzstein 8393a35b93dc582e38ff8ee5979754a16b4bf4da0cSam Blitzstein final int centerV; 8493a35b93dc582e38ff8ee5979754a16b4bf4da0cSam Blitzstein if (absoluteFrac) { 8593a35b93dc582e38ff8ee5979754a16b4bf4da0cSam Blitzstein final int minCenterV = srcHalfSliceH; 8693a35b93dc582e38ff8ee5979754a16b4bf4da0cSam Blitzstein final int maxCenterV = srcH - srcHalfSliceH; 8793a35b93dc582e38ff8ee5979754a16b4bf4da0cSam Blitzstein centerV = Math.max(minCenterV, Math.min(maxCenterV, Math.round(srcH * vertSliceFrac))); 8893a35b93dc582e38ff8ee5979754a16b4bf4da0cSam Blitzstein } else { 8993a35b93dc582e38ff8ee5979754a16b4bf4da0cSam Blitzstein centerV = Math 9093a35b93dc582e38ff8ee5979754a16b4bf4da0cSam Blitzstein .round(Math.abs(srcH - srcCroppedSliceH) * vertSliceFrac + srcHalfSliceH); 9193a35b93dc582e38ff8ee5979754a16b4bf4da0cSam Blitzstein } 9293a35b93dc582e38ff8ee5979754a16b4bf4da0cSam Blitzstein 9393a35b93dc582e38ff8ee5979754a16b4bf4da0cSam Blitzstein outRect.top = centerV - srcCroppedH / 2; 9493a35b93dc582e38ff8ee5979754a16b4bf4da0cSam Blitzstein outRect.bottom = outRect.top + srcCroppedH; 9593a35b93dc582e38ff8ee5979754a16b4bf4da0cSam Blitzstein } 9693a35b93dc582e38ff8ee5979754a16b4bf4da0cSam Blitzstein 9793a35b93dc582e38ff8ee5979754a16b4bf4da0cSam Blitzstein /** 9893a35b93dc582e38ff8ee5979754a16b4bf4da0cSam Blitzstein * @param srcW 9993a35b93dc582e38ff8ee5979754a16b4bf4da0cSam Blitzstein * @param srcH 10093a35b93dc582e38ff8ee5979754a16b4bf4da0cSam Blitzstein * @param dstW 10193a35b93dc582e38ff8ee5979754a16b4bf4da0cSam Blitzstein * @param dstH 10293a35b93dc582e38ff8ee5979754a16b4bf4da0cSam Blitzstein * @param outRect 10393a35b93dc582e38ff8ee5979754a16b4bf4da0cSam Blitzstein */ 10493a35b93dc582e38ff8ee5979754a16b4bf4da0cSam Blitzstein public static void calculateCroppedSrcRect(int srcW, int srcH, int dstW, int dstH, 10593a35b93dc582e38ff8ee5979754a16b4bf4da0cSam Blitzstein Rect outRect) { 10693a35b93dc582e38ff8ee5979754a16b4bf4da0cSam Blitzstein calculateCroppedSrcRect(srcW, srcH, dstW, dstH, Integer.MAX_VALUE, outRect); 10793a35b93dc582e38ff8ee5979754a16b4bf4da0cSam Blitzstein } 10893a35b93dc582e38ff8ee5979754a16b4bf4da0cSam Blitzstein 10993a35b93dc582e38ff8ee5979754a16b4bf4da0cSam Blitzstein public static void calculateCroppedSrcRect(int srcW, int srcH, int dstW, int dstH, 11093a35b93dc582e38ff8ee5979754a16b4bf4da0cSam Blitzstein int sampleSize, Rect outRect) { 11193a35b93dc582e38ff8ee5979754a16b4bf4da0cSam Blitzstein if (sampleSize < 1) { 11293a35b93dc582e38ff8ee5979754a16b4bf4da0cSam Blitzstein sampleSize = 1; 11393a35b93dc582e38ff8ee5979754a16b4bf4da0cSam Blitzstein } 11493a35b93dc582e38ff8ee5979754a16b4bf4da0cSam Blitzstein final float regularScale = Math.min( 11593a35b93dc582e38ff8ee5979754a16b4bf4da0cSam Blitzstein (float) srcW / dstW, 11693a35b93dc582e38ff8ee5979754a16b4bf4da0cSam Blitzstein (float) srcH / dstH); 11793a35b93dc582e38ff8ee5979754a16b4bf4da0cSam Blitzstein 11893a35b93dc582e38ff8ee5979754a16b4bf4da0cSam Blitzstein final float scale = Math.min(sampleSize, regularScale); 11993a35b93dc582e38ff8ee5979754a16b4bf4da0cSam Blitzstein 12093a35b93dc582e38ff8ee5979754a16b4bf4da0cSam Blitzstein final int srcCroppedW = Math.round(dstW * scale); 12193a35b93dc582e38ff8ee5979754a16b4bf4da0cSam Blitzstein final int srcCroppedH = Math.round(dstH * scale); 12293a35b93dc582e38ff8ee5979754a16b4bf4da0cSam Blitzstein 12393a35b93dc582e38ff8ee5979754a16b4bf4da0cSam Blitzstein outRect.left = (srcW - srcCroppedW) / 2; 12493a35b93dc582e38ff8ee5979754a16b4bf4da0cSam Blitzstein outRect.right = outRect.left + srcCroppedW; 12593a35b93dc582e38ff8ee5979754a16b4bf4da0cSam Blitzstein 12693a35b93dc582e38ff8ee5979754a16b4bf4da0cSam Blitzstein outRect.top = (srcH - srcCroppedH) / 2; 12793a35b93dc582e38ff8ee5979754a16b4bf4da0cSam Blitzstein outRect.bottom = outRect.top + srcCroppedH; 12893a35b93dc582e38ff8ee5979754a16b4bf4da0cSam Blitzstein } 12993a35b93dc582e38ff8ee5979754a16b4bf4da0cSam Blitzstein} 130