Revert "Move wallpaper picker code to a separate directory"
This reverts commit 8e88cb8478.
This commit is contained in:
@@ -1,260 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2010 The Android Open Source Project
|
||||
*
|
||||
* 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 com.android.gallery3d.common;
|
||||
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.Bitmap.CompressFormat;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Matrix;
|
||||
import android.graphics.Paint;
|
||||
import android.os.Build;
|
||||
import android.util.FloatMath;
|
||||
import android.util.Log;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
public class BitmapUtils {
|
||||
private static final String TAG = "BitmapUtils";
|
||||
private static final int DEFAULT_JPEG_QUALITY = 90;
|
||||
public static final int UNCONSTRAINED = -1;
|
||||
|
||||
private BitmapUtils(){}
|
||||
|
||||
/*
|
||||
* Compute the sample size as a function of minSideLength
|
||||
* and maxNumOfPixels.
|
||||
* minSideLength is used to specify that minimal width or height of a
|
||||
* bitmap.
|
||||
* maxNumOfPixels is used to specify the maximal size in pixels that is
|
||||
* tolerable in terms of memory usage.
|
||||
*
|
||||
* The function returns a sample size based on the constraints.
|
||||
* Both size and minSideLength can be passed in as UNCONSTRAINED,
|
||||
* which indicates no care of the corresponding constraint.
|
||||
* The functions prefers returning a sample size that
|
||||
* generates a smaller bitmap, unless minSideLength = UNCONSTRAINED.
|
||||
*
|
||||
* Also, the function rounds up the sample size to a power of 2 or multiple
|
||||
* of 8 because BitmapFactory only honors sample size this way.
|
||||
* For example, BitmapFactory downsamples an image by 2 even though the
|
||||
* request is 3. So we round up the sample size to avoid OOM.
|
||||
*/
|
||||
public static int computeSampleSize(int width, int height,
|
||||
int minSideLength, int maxNumOfPixels) {
|
||||
int initialSize = computeInitialSampleSize(
|
||||
width, height, minSideLength, maxNumOfPixels);
|
||||
|
||||
return initialSize <= 8
|
||||
? Utils.nextPowerOf2(initialSize)
|
||||
: (initialSize + 7) / 8 * 8;
|
||||
}
|
||||
|
||||
private static int computeInitialSampleSize(int w, int h,
|
||||
int minSideLength, int maxNumOfPixels) {
|
||||
if (maxNumOfPixels == UNCONSTRAINED
|
||||
&& minSideLength == UNCONSTRAINED) return 1;
|
||||
|
||||
int lowerBound = (maxNumOfPixels == UNCONSTRAINED) ? 1 :
|
||||
(int) FloatMath.ceil(FloatMath.sqrt((float) (w * h) / maxNumOfPixels));
|
||||
|
||||
if (minSideLength == UNCONSTRAINED) {
|
||||
return lowerBound;
|
||||
} else {
|
||||
int sampleSize = Math.min(w / minSideLength, h / minSideLength);
|
||||
return Math.max(sampleSize, lowerBound);
|
||||
}
|
||||
}
|
||||
|
||||
// This computes a sample size which makes the longer side at least
|
||||
// minSideLength long. If that's not possible, return 1.
|
||||
public static int computeSampleSizeLarger(int w, int h,
|
||||
int minSideLength) {
|
||||
int initialSize = Math.max(w / minSideLength, h / minSideLength);
|
||||
if (initialSize <= 1) return 1;
|
||||
|
||||
return initialSize <= 8
|
||||
? Utils.prevPowerOf2(initialSize)
|
||||
: initialSize / 8 * 8;
|
||||
}
|
||||
|
||||
// Find the min x that 1 / x >= scale
|
||||
public static int computeSampleSizeLarger(float scale) {
|
||||
int initialSize = (int) FloatMath.floor(1f / scale);
|
||||
if (initialSize <= 1) return 1;
|
||||
|
||||
return initialSize <= 8
|
||||
? Utils.prevPowerOf2(initialSize)
|
||||
: initialSize / 8 * 8;
|
||||
}
|
||||
|
||||
// Find the max x that 1 / x <= scale.
|
||||
public static int computeSampleSize(float scale) {
|
||||
Utils.assertTrue(scale > 0);
|
||||
int initialSize = Math.max(1, (int) FloatMath.ceil(1 / scale));
|
||||
return initialSize <= 8
|
||||
? Utils.nextPowerOf2(initialSize)
|
||||
: (initialSize + 7) / 8 * 8;
|
||||
}
|
||||
|
||||
public static Bitmap resizeBitmapByScale(
|
||||
Bitmap bitmap, float scale, boolean recycle) {
|
||||
int width = Math.round(bitmap.getWidth() * scale);
|
||||
int height = Math.round(bitmap.getHeight() * scale);
|
||||
if (width == bitmap.getWidth()
|
||||
&& height == bitmap.getHeight()) return bitmap;
|
||||
Bitmap target = Bitmap.createBitmap(width, height, getConfig(bitmap));
|
||||
Canvas canvas = new Canvas(target);
|
||||
canvas.scale(scale, scale);
|
||||
Paint paint = new Paint(Paint.FILTER_BITMAP_FLAG | Paint.DITHER_FLAG);
|
||||
canvas.drawBitmap(bitmap, 0, 0, paint);
|
||||
if (recycle) bitmap.recycle();
|
||||
return target;
|
||||
}
|
||||
|
||||
private static Bitmap.Config getConfig(Bitmap bitmap) {
|
||||
Bitmap.Config config = bitmap.getConfig();
|
||||
if (config == null) {
|
||||
config = Bitmap.Config.ARGB_8888;
|
||||
}
|
||||
return config;
|
||||
}
|
||||
|
||||
public static Bitmap resizeDownBySideLength(
|
||||
Bitmap bitmap, int maxLength, boolean recycle) {
|
||||
int srcWidth = bitmap.getWidth();
|
||||
int srcHeight = bitmap.getHeight();
|
||||
float scale = Math.min(
|
||||
(float) maxLength / srcWidth, (float) maxLength / srcHeight);
|
||||
if (scale >= 1.0f) return bitmap;
|
||||
return resizeBitmapByScale(bitmap, scale, recycle);
|
||||
}
|
||||
|
||||
public static Bitmap resizeAndCropCenter(Bitmap bitmap, int size, boolean recycle) {
|
||||
int w = bitmap.getWidth();
|
||||
int h = bitmap.getHeight();
|
||||
if (w == size && h == size) return bitmap;
|
||||
|
||||
// scale the image so that the shorter side equals to the target;
|
||||
// the longer side will be center-cropped.
|
||||
float scale = (float) size / Math.min(w, h);
|
||||
|
||||
Bitmap target = Bitmap.createBitmap(size, size, getConfig(bitmap));
|
||||
int width = Math.round(scale * bitmap.getWidth());
|
||||
int height = Math.round(scale * bitmap.getHeight());
|
||||
Canvas canvas = new Canvas(target);
|
||||
canvas.translate((size - width) / 2f, (size - height) / 2f);
|
||||
canvas.scale(scale, scale);
|
||||
Paint paint = new Paint(Paint.FILTER_BITMAP_FLAG | Paint.DITHER_FLAG);
|
||||
canvas.drawBitmap(bitmap, 0, 0, paint);
|
||||
if (recycle) bitmap.recycle();
|
||||
return target;
|
||||
}
|
||||
|
||||
public static void recycleSilently(Bitmap bitmap) {
|
||||
if (bitmap == null) return;
|
||||
try {
|
||||
bitmap.recycle();
|
||||
} catch (Throwable t) {
|
||||
Log.w(TAG, "unable recycle bitmap", t);
|
||||
}
|
||||
}
|
||||
|
||||
public static Bitmap rotateBitmap(Bitmap source, int rotation, boolean recycle) {
|
||||
if (rotation == 0) return source;
|
||||
int w = source.getWidth();
|
||||
int h = source.getHeight();
|
||||
Matrix m = new Matrix();
|
||||
m.postRotate(rotation);
|
||||
Bitmap bitmap = Bitmap.createBitmap(source, 0, 0, w, h, m, true);
|
||||
if (recycle) source.recycle();
|
||||
return bitmap;
|
||||
}
|
||||
|
||||
public static Bitmap createVideoThumbnail(String filePath) {
|
||||
// MediaMetadataRetriever is available on API Level 8
|
||||
// but is hidden until API Level 10
|
||||
Class<?> clazz = null;
|
||||
Object instance = null;
|
||||
try {
|
||||
clazz = Class.forName("android.media.MediaMetadataRetriever");
|
||||
instance = clazz.newInstance();
|
||||
|
||||
Method method = clazz.getMethod("setDataSource", String.class);
|
||||
method.invoke(instance, filePath);
|
||||
|
||||
// The method name changes between API Level 9 and 10.
|
||||
if (Build.VERSION.SDK_INT <= 9) {
|
||||
return (Bitmap) clazz.getMethod("captureFrame").invoke(instance);
|
||||
} else {
|
||||
byte[] data = (byte[]) clazz.getMethod("getEmbeddedPicture").invoke(instance);
|
||||
if (data != null) {
|
||||
Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
|
||||
if (bitmap != null) return bitmap;
|
||||
}
|
||||
return (Bitmap) clazz.getMethod("getFrameAtTime").invoke(instance);
|
||||
}
|
||||
} catch (IllegalArgumentException ex) {
|
||||
// Assume this is a corrupt video file
|
||||
} catch (RuntimeException ex) {
|
||||
// Assume this is a corrupt video file.
|
||||
} catch (InstantiationException e) {
|
||||
Log.e(TAG, "createVideoThumbnail", e);
|
||||
} catch (InvocationTargetException e) {
|
||||
Log.e(TAG, "createVideoThumbnail", e);
|
||||
} catch (ClassNotFoundException e) {
|
||||
Log.e(TAG, "createVideoThumbnail", e);
|
||||
} catch (NoSuchMethodException e) {
|
||||
Log.e(TAG, "createVideoThumbnail", e);
|
||||
} catch (IllegalAccessException e) {
|
||||
Log.e(TAG, "createVideoThumbnail", e);
|
||||
} finally {
|
||||
try {
|
||||
if (instance != null) {
|
||||
clazz.getMethod("release").invoke(instance);
|
||||
}
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static byte[] compressToBytes(Bitmap bitmap) {
|
||||
return compressToBytes(bitmap, DEFAULT_JPEG_QUALITY);
|
||||
}
|
||||
|
||||
public static byte[] compressToBytes(Bitmap bitmap, int quality) {
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream(65536);
|
||||
bitmap.compress(CompressFormat.JPEG, quality, baos);
|
||||
return baos.toByteArray();
|
||||
}
|
||||
|
||||
public static boolean isSupportedByRegionDecoder(String mimeType) {
|
||||
if (mimeType == null) return false;
|
||||
mimeType = mimeType.toLowerCase();
|
||||
return mimeType.startsWith("image/") &&
|
||||
(!mimeType.equals("image/gif") && !mimeType.endsWith("bmp"));
|
||||
}
|
||||
|
||||
public static boolean isRotationSupported(String mimeType) {
|
||||
if (mimeType == null) return false;
|
||||
mimeType = mimeType.toLowerCase();
|
||||
return mimeType.equals("image/jpeg");
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user