Back to project page imageCropLib.
The source code is released under:
GNU Lesser General Public License
If you think the Android project imageCropLib listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.
package com.mhk.android.croplib; /*//w w w . ja v a 2 s . c o m * Copyright (C) 2009 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. */ import java.io.Closeable; import java.io.File; import java.io.IOException; import java.io.InputStream; import android.annotation.SuppressLint; import android.content.ContentResolver; import android.content.Context; import android.database.Cursor; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.BitmapRegionDecoder; import android.graphics.Matrix; import android.graphics.Rect; import android.graphics.RectF; import android.media.ExifInterface; import android.net.Uri; import android.opengl.GLES10; import android.provider.MediaStore; import android.text.TextUtils; import android.util.Log; /* * Modified from original in AOSP. */ @SuppressLint("NewApi") public class CropUtil { private static final String SCHEME_FILE = "file"; private static final String SCHEME_CONTENT = "content"; private static final int SIZE_DEFAULT = 2048; private static final int SIZE_LIMIT = 4096; public static void closeSilently(Closeable c) { if (c == null) return; try { c.close(); } catch (Throwable t) { // Do nothing } } public static int getExifRotation(File imageFile) { if (imageFile == null) return 0; try { ExifInterface exif = new ExifInterface(imageFile.getAbsolutePath()); // We only recognize a subset of orientation tag values switch (exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_UNDEFINED)) { case ExifInterface.ORIENTATION_ROTATE_90: return 90; case ExifInterface.ORIENTATION_ROTATE_180: return 180; case ExifInterface.ORIENTATION_ROTATE_270: return 270; default: return ExifInterface.ORIENTATION_UNDEFINED; } } catch (IOException e) { return 0; } } public static boolean copyExifRotation(File sourceFile, File destFile) { if (sourceFile == null || destFile == null) return false; try { ExifInterface exifSource = new ExifInterface(sourceFile.getAbsolutePath()); ExifInterface exifDest = new ExifInterface(destFile.getAbsolutePath()); exifDest.setAttribute(ExifInterface.TAG_ORIENTATION, exifSource.getAttribute(ExifInterface.TAG_ORIENTATION)); exifDest.saveAttributes(); return true; } catch (IOException e) { return false; } } public static File getFromMediaUri(ContentResolver resolver, Uri uri) { if (uri == null) return null; if (SCHEME_FILE.equals(uri.getScheme())) { return new File(uri.getPath()); } else if (SCHEME_CONTENT.equals(uri.getScheme())) { final String[] filePathColumn = { MediaStore.MediaColumns.DATA, MediaStore.MediaColumns.DISPLAY_NAME }; Cursor cursor = null; try { cursor = resolver.query(uri, filePathColumn, null, null, null); if (cursor != null && cursor.moveToFirst()) { final int columnIndex = (uri.toString().startsWith("content://com.google.android.gallery3d")) ? cursor.getColumnIndex(MediaStore.MediaColumns.DISPLAY_NAME) : cursor.getColumnIndex(MediaStore.MediaColumns.DATA); // Picasa image on newer devices with Honeycomb and up if (columnIndex != -1) { String filePath = cursor.getString(columnIndex); if (!TextUtils.isEmpty(filePath)) { return new File(filePath); } } } } catch (SecurityException ignored) { // Nothing we can do } finally { if (cursor != null) cursor.close(); } } return null; } public static Bitmap decodeRegionCrop(Context context, Uri sourceUri, Rect rect) { Bitmap croppedImage=null; InputStream is = null; try { is = context.getContentResolver().openInputStream(sourceUri); BitmapRegionDecoder decoder = BitmapRegionDecoder.newInstance(is, false); final int width = decoder.getWidth(); final int height = decoder.getHeight(); int exifRotation = CropUtil.getExifRotation(CropUtil.getFromMediaUri(context.getContentResolver(), sourceUri)); if (exifRotation != 0) { // Adjust crop area to account for image rotation Matrix matrix = new Matrix(); matrix.setRotate(-exifRotation); RectF adjusted = new RectF(); matrix.mapRect(adjusted, new RectF(rect)); // Adjust to account for origin at 0,0 adjusted.offset(adjusted.left < 0 ? width : 0, adjusted.top < 0 ? height : 0); rect = new Rect((int) adjusted.left, (int) adjusted.top, (int) adjusted.right, (int) adjusted.bottom); } try { croppedImage = decoder.decodeRegion(rect, new BitmapFactory.Options()); } catch (IllegalArgumentException e) { // Rethrow with some extra information throw new IllegalArgumentException("Rectangle " + rect + " is outside of the image (" + width + "," + height + "," + exifRotation + ")", e); } } catch (IOException e) { } catch (OutOfMemoryError e) { } finally { CropUtil.closeSilently(is); } return croppedImage; } public static int calculateBitmapSampleSize(Context context, Uri bitmapUri) throws IOException { InputStream is = null; BitmapFactory.Options options = new BitmapFactory.Options(); options.inJustDecodeBounds = true; try { is = context.getContentResolver().openInputStream(bitmapUri); BitmapFactory.decodeStream(is, null, options); // Just get image size } finally { CropUtil.closeSilently(is); } int maxSize = getMaxImageSize(); int sampleSize = 1; while (options.outHeight / sampleSize > maxSize || options.outWidth / sampleSize > maxSize) { sampleSize = sampleSize << 1; } Log.d("SAMPLE", "max:"+maxSize+", sample:"+sampleSize); return sampleSize; } private static int getMaxImageSize() { int textureLimit = getMaxTextureSize(); if (textureLimit == 0) { return SIZE_DEFAULT; } else { return Math.min(textureLimit, SIZE_LIMIT); } } private static int getMaxTextureSize() { // The OpenGL texture size is the maximum size that can be drawn in an ImageView int[] maxSize = new int[1]; GLES10.glGetIntegerv(GLES10.GL_MAX_TEXTURE_SIZE, maxSize, 0); return maxSize[0]; } }