/*
* 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.process;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.RectF;
import me.xiaopan.sketch.Sketch;
import me.xiaopan.sketch.cache.BitmapPool;
import me.xiaopan.sketch.request.Resize;
/**
* 旋转图片处理器
*/
@SuppressWarnings("unused")
public class RotateImageProcessor extends WrappedImageProcessor {
protected String logName = "RotateImageProcessor";
private int degrees;
public RotateImageProcessor(int degrees, WrappedImageProcessor wrappedImageProcessor) {
super(wrappedImageProcessor);
this.degrees = degrees;
}
public RotateImageProcessor(int degrees) {
this(degrees, null);
}
@Override
public Bitmap onProcess(Sketch sketch, Bitmap bitmap, Resize resize, boolean forceUseResize, boolean lowQualityImage) {
if (bitmap == null || bitmap.isRecycled() || degrees % 360 == 0) {
return bitmap;
}
return rotate(bitmap, degrees, sketch.getConfiguration().getBitmapPool());
}
@Override
public String onGetKey() {
// 0度或360度时不加标识,这样做是为了避免浪费合适的内存缓存
if (degrees % 360 == 0) {
return null;
} else {
return String.format("%s(degrees=%d)", logName, degrees);
}
}
public static Bitmap rotate(Bitmap bitmap, int degrees, BitmapPool bitmapPool){
Matrix matrix = new Matrix();
matrix.setRotate(degrees);
// 根据旋转角度计算新的图片的尺寸
RectF dstR = new RectF(0, 0, bitmap.getWidth(), bitmap.getHeight());
RectF deviceR = new RectF();
matrix.mapRect(deviceR, dstR);
int newWidth = (int) deviceR.width();
int newHeight = (int) deviceR.height();
// 创建新图片
Bitmap.Config config = bitmap.getConfig() != null ? bitmap.getConfig() : null;
if (degrees % 90 != 0 && config != Bitmap.Config.ARGB_8888) { // 角度不能整除90°时新图片会是斜的,因此要支持透明度,这样倾斜导致露出的部分就不会是黑的
config = Bitmap.Config.ARGB_8888;
}
Bitmap rotateBitmap = bitmapPool.getOrMake(newWidth, newHeight, config);
// 绘制
Canvas canvas = new Canvas(rotateBitmap);
canvas.translate(-deviceR.left, -deviceR.top);
canvas.concat(matrix);
Paint paint = new Paint();
Rect srcR = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight());
canvas.drawBitmap(bitmap, srcR, dstR, paint);
return rotateBitmap;
}
}