/* * Copyright (C) 2013 Peng fei Pan <sky@xiaopan.me> * * 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 me.xiaopan.sketch.feature; import android.graphics.Rect; import android.widget.ImageView; import me.xiaopan.sketch.Identifier; /** * 用来计算resize */ public class ResizeCalculator implements Identifier { protected String logName = "ResizeCalculator"; public static Rect srcMappingStartRect(int originalImageWidth, int originalImageHeight, int targetImageWidth, int targetImageHeight) { float widthScale = (float) originalImageWidth / targetImageWidth; float heightScale = (float) originalImageHeight / targetImageHeight; float finalScale = widthScale < heightScale ? widthScale : heightScale; int srcWidth = (int) (targetImageWidth * finalScale); int srcHeight = (int) (targetImageHeight * finalScale); int srcLeft = 0; int srcTop = 0; return new Rect(srcLeft, srcTop, srcLeft + srcWidth, srcTop + srcHeight); } public static Rect srcMappingCenterRect(int originalImageWidth, int originalImageHeight, int targetImageWidth, int targetImageHeight) { float widthScale = (float) originalImageWidth / targetImageWidth; float heightScale = (float) originalImageHeight / targetImageHeight; float finalScale = widthScale < heightScale ? widthScale : heightScale; int srcWidth = (int) (targetImageWidth * finalScale); int srcHeight = (int) (targetImageHeight * finalScale); int srcLeft = (originalImageWidth - srcWidth) / 2; int srcTop = (originalImageHeight - srcHeight) / 2; return new Rect(srcLeft, srcTop, srcLeft + srcWidth, srcTop + srcHeight); } public static Rect srcMappingEndRect(int originalImageWidth, int originalImageHeight, int targetImageWidth, int targetImageHeight) { float widthScale = (float) originalImageWidth / targetImageWidth; float heightScale = (float) originalImageHeight / targetImageHeight; float finalScale = widthScale < heightScale ? widthScale : heightScale; int srcWidth = (int) (targetImageWidth * finalScale); int srcHeight = (int) (targetImageHeight * finalScale); int srcLeft; int srcTop; if (originalImageWidth > originalImageHeight) { srcLeft = originalImageWidth - srcWidth; srcTop = originalImageHeight - srcHeight; } else { srcLeft = originalImageWidth - srcWidth; srcTop = originalImageHeight - srcHeight; } return new Rect(srcLeft, srcTop, srcLeft + srcWidth, srcTop + srcHeight); } public static Rect srcMatrixRect(int originalImageWidth, int originalImageHeight, int targetImageWidth, int targetImageHeight) { if (originalImageWidth > targetImageWidth && originalImageHeight > targetImageHeight) { return new Rect(0, 0, targetImageWidth, targetImageHeight); } else { float scale = targetImageWidth - originalImageWidth > targetImageHeight - originalImageHeight ? (float) targetImageWidth / originalImageWidth : (float) targetImageHeight / originalImageHeight; int srcWidth = (int) (targetImageWidth / scale); int srcHeight = (int) (targetImageHeight / scale); int srcLeft = 0; int srcTop = 0; return new Rect(srcLeft, srcTop, srcLeft + srcWidth, srcTop + srcHeight); } } public static int[] scaleTargetSize(int originalImageWidth, int originalImageHeight, int targetImageWidth, int targetImageHeight) { if (targetImageWidth > originalImageWidth || targetImageHeight > originalImageHeight) { float scale = Math.abs(targetImageWidth - originalImageWidth) < Math.abs(targetImageHeight - originalImageHeight) ? (float) targetImageWidth / originalImageWidth : (float) targetImageHeight / originalImageHeight; targetImageWidth = Math.round(targetImageWidth / scale); targetImageHeight = Math.round(targetImageHeight / scale); } return new int[]{targetImageWidth, targetImageHeight}; } @Override public String getKey() { return logName; } /** * 计算 * * @param imageWidth 图片原始宽 * @param imageHeight 图片原始高 * @param resizeWidth 目标宽 * @param resizeHeight 目标高 * @param scaleType 缩放类型 * @param forceUseResize 强制使用resize * @return 计算结果 */ public Result calculator(int imageWidth, int imageHeight, int resizeWidth, int resizeHeight, ImageView.ScaleType scaleType, boolean forceUseResize) { if (imageWidth == resizeWidth && imageHeight == resizeHeight) { Result result = new Result(); result.imageWidth = imageWidth; result.imageHeight = imageHeight; result.srcRect = new Rect(0, 0, imageWidth, imageHeight); result.destRect = result.srcRect; return result; } if (scaleType == null) { scaleType = ImageView.ScaleType.FIT_CENTER; } int newImageWidth; int newImageHeight; if (forceUseResize) { newImageWidth = resizeWidth; newImageHeight = resizeHeight; } else { int[] finalImageSize = scaleTargetSize(imageWidth, imageHeight, resizeWidth, resizeHeight); newImageWidth = finalImageSize[0]; newImageHeight = finalImageSize[1]; } Rect srcRect; Rect destRect = new Rect(0, 0, newImageWidth, newImageHeight); if (scaleType == ImageView.ScaleType.CENTER || scaleType == ImageView.ScaleType.CENTER_CROP || scaleType == ImageView.ScaleType.CENTER_INSIDE) { srcRect = srcMappingCenterRect(imageWidth, imageHeight, newImageWidth, newImageHeight); } else if (scaleType == ImageView.ScaleType.FIT_START) { srcRect = srcMappingStartRect(imageWidth, imageHeight, newImageWidth, newImageHeight); } else if (scaleType == ImageView.ScaleType.FIT_CENTER) { srcRect = srcMappingCenterRect(imageWidth, imageHeight, newImageWidth, newImageHeight); } else if (scaleType == ImageView.ScaleType.FIT_END) { srcRect = srcMappingEndRect(imageWidth, imageHeight, newImageWidth, newImageHeight); } else if (scaleType == ImageView.ScaleType.FIT_XY) { srcRect = new Rect(0, 0, imageWidth, imageHeight); } else if (scaleType == ImageView.ScaleType.MATRIX) { srcRect = srcMatrixRect(imageWidth, imageHeight, newImageWidth, newImageHeight); } else { srcRect = srcMappingCenterRect(imageWidth, imageHeight, newImageWidth, newImageHeight); } Result result = new Result(); result.imageWidth = newImageWidth; result.imageHeight = newImageHeight; result.srcRect = srcRect; result.destRect = destRect; return result; } public static class Result { public int imageWidth; public int imageHeight; public Rect srcRect; public Rect destRect; } }