Initial commit
This commit is contained in:
@@ -0,0 +1,673 @@
|
||||
package com.mogo.utils;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.ContentUris;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.database.Cursor;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Matrix;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.PorterDuff;
|
||||
import android.graphics.PorterDuffXfermode;
|
||||
import android.graphics.RectF;
|
||||
import android.media.ExifInterface;
|
||||
import android.media.MediaMetadataRetriever;
|
||||
import android.net.Uri;
|
||||
import android.opengl.GLES10;
|
||||
import android.os.Build;
|
||||
import android.provider.DocumentsContract;
|
||||
import android.provider.MediaStore;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Base64;
|
||||
import android.util.Log;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.InputStream;
|
||||
|
||||
import javax.microedition.khronos.egl.EGL10;
|
||||
import javax.microedition.khronos.egl.EGLConfig;
|
||||
import javax.microedition.khronos.egl.EGLContext;
|
||||
import javax.microedition.khronos.egl.EGLDisplay;
|
||||
|
||||
/**
|
||||
* @author wangzhiyuan
|
||||
* @since 2017/8/30
|
||||
*/
|
||||
|
||||
public class BitmapHelper {
|
||||
private static final String TAG = "BitmapHelper";
|
||||
|
||||
static int ONE_KB = 1024;
|
||||
static int ONE_MB = ONE_KB * 1024;
|
||||
|
||||
static int SIZE_DEFAULT = 2048;
|
||||
static int SIZE_LIMIT = 2048;
|
||||
|
||||
/**
|
||||
* 根据原图添加圆角
|
||||
*
|
||||
* @param source
|
||||
* @return
|
||||
*/
|
||||
public static Bitmap createRoundCornerImage( Bitmap source, float corner ) {
|
||||
final Paint paint = new Paint();
|
||||
paint.setAntiAlias( true );
|
||||
Bitmap target = Bitmap.createBitmap( source.getWidth(), source.getHeight(), Bitmap.Config.ARGB_8888 );
|
||||
Canvas canvas = new Canvas( target );
|
||||
RectF rect = new RectF( 0, 0, source.getWidth(), source.getHeight() );
|
||||
canvas.drawRoundRect( rect, corner, corner, paint );
|
||||
paint.setXfermode( new PorterDuffXfermode( PorterDuff.Mode.SRC_IN ) );
|
||||
canvas.drawBitmap( source, 0, 0, paint );
|
||||
return target;
|
||||
}
|
||||
|
||||
public static byte[] bitmapToBytes( Bitmap bitmap ) {
|
||||
if ( bitmap == null ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
ByteArrayOutputStream bos = null;
|
||||
byte[] result = null;
|
||||
|
||||
try {
|
||||
bos = new ByteArrayOutputStream();
|
||||
bitmap.compress( Bitmap.CompressFormat.JPEG, 100, bos );
|
||||
result = bos.toByteArray();
|
||||
} catch ( Exception e ) {
|
||||
e.printStackTrace();
|
||||
result = null;
|
||||
} finally {
|
||||
IOUtils.closeSilently( bos );
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Use quality compression to compress bitmap's size to be smaller than a max size, and convert it to bytes thereafter.
|
||||
* Note that this method will not report compressing ratio related data.
|
||||
*
|
||||
* @param bitmap data source
|
||||
* @param maxSize unit in kb
|
||||
* @return bytes after compressing bitmap to a size smaller than a specific max size.
|
||||
*/
|
||||
public static byte[] bitmapToBytes( Bitmap bitmap, int maxSize ) {
|
||||
final long start = System.currentTimeMillis();
|
||||
|
||||
if ( bitmap == null ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
final int maxSizeOfBytes = maxSize * ONE_KB;
|
||||
ByteArrayOutputStream bos = null;
|
||||
byte[] result = null;
|
||||
|
||||
try {
|
||||
bos = new ByteArrayOutputStream();
|
||||
int quality = 100;
|
||||
int fullSize = 0;
|
||||
|
||||
do {
|
||||
bos.reset();
|
||||
bitmap.compress( Bitmap.CompressFormat.JPEG, quality, bos );
|
||||
if ( quality == 100 ) {
|
||||
fullSize = bos.size();
|
||||
}
|
||||
Log.i( TAG, "quality<---->size, " + quality + "<---->" + bos.size() / 1024 );
|
||||
}
|
||||
while ( bos.size() > maxSizeOfBytes && ( quality -= ( fullSize > ONE_MB ) ? 10 : 5 ) >= 0 );
|
||||
|
||||
result = bos.toByteArray();
|
||||
|
||||
final long end = System.currentTimeMillis();
|
||||
Log.i( TAG,
|
||||
"bitmap to bytes costs " + ( end - start ) + "ms, \n" +
|
||||
"bitmap full size is " + ( fullSize / 1024 ) + "kb, \n" +
|
||||
"bitmap final size is " + ( bos.size() / 1024 ) + "kb, \n" +
|
||||
"bitmap quality is " + quality );
|
||||
} catch ( Exception e ) {
|
||||
e.printStackTrace();
|
||||
result = null;
|
||||
} finally {
|
||||
IOUtils.closeSilently( bos );
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Use quality compression to compress bitmap to be smaller than a specific max size.
|
||||
*
|
||||
* @param bitmap data source
|
||||
* @param maxSize a specific max size which's unit is kb.
|
||||
* @return a compressed bitmap smaller than the max size.
|
||||
*/
|
||||
public static Bitmap compressBitmap( Bitmap bitmap, int maxSize, final OnCompressListener listener ) {
|
||||
if ( bitmap == null || bitmap.isRecycled() ) {
|
||||
return null;
|
||||
}
|
||||
listener.onBeforeCompress();
|
||||
ByteArrayOutputStream bos = null;
|
||||
Bitmap target = null;
|
||||
|
||||
try {
|
||||
bos = new ByteArrayOutputStream();
|
||||
int quality = 100;
|
||||
|
||||
do {
|
||||
bos.reset();
|
||||
bitmap.compress( Bitmap.CompressFormat.JPEG, quality, bos );
|
||||
}
|
||||
while ( bos.size() / 1024 > maxSize && ( quality -= 5 ) >= 0 );
|
||||
|
||||
byte[] result = bos.toByteArray();
|
||||
target = bytesToBitmap( result );
|
||||
if ( listener != null ) {
|
||||
listener.onCompressSuccess( result );
|
||||
}
|
||||
} catch ( Exception e ) {
|
||||
e.printStackTrace();
|
||||
target = null;
|
||||
if ( listener != null ) {
|
||||
listener.onCompressFailed( "压缩失败" );
|
||||
}
|
||||
} finally {
|
||||
IOUtils.closeSilently( bos );
|
||||
}
|
||||
|
||||
return target;
|
||||
}
|
||||
|
||||
|
||||
public static Bitmap compressBitmap( Bitmap bitmap, int maxSize ) {
|
||||
if ( bitmap == null ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
ByteArrayOutputStream bos = null;
|
||||
Bitmap target = null;
|
||||
|
||||
try {
|
||||
bos = new ByteArrayOutputStream();
|
||||
int quality = 100;
|
||||
|
||||
do {
|
||||
bos.reset();
|
||||
bitmap.compress( Bitmap.CompressFormat.JPEG, quality, bos );
|
||||
}
|
||||
while ( bos.size() / 1024 > maxSize && ( quality -= 5 ) >= 0 );
|
||||
|
||||
byte[] result = bos.toByteArray();
|
||||
target = bytesToBitmap( result );
|
||||
} catch ( Exception e ) {
|
||||
e.printStackTrace();
|
||||
target = null;
|
||||
} finally {
|
||||
IOUtils.closeSilently( bos );
|
||||
}
|
||||
|
||||
return target;
|
||||
}
|
||||
|
||||
/**
|
||||
* Decode an immutable bitmap from the specified byte array.
|
||||
*
|
||||
* @param b byte array of compressed image data
|
||||
* @return an immutable bitmap or null in case of exception.
|
||||
*/
|
||||
public static Bitmap bytesToBitmap( byte[] b ) {
|
||||
if ( b != null && b.length != 0 ) {
|
||||
return BitmapFactory.decodeByteArray( b, 0, b.length );
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Decode an immutable bitmap from the specified byte array.
|
||||
*
|
||||
* @param b byte array of compressed image data
|
||||
* @param options Options that control downsampling and whether the
|
||||
* image should be completely decoded, or just is size returned.
|
||||
* @return an immutable bitmap or null in case of exception.
|
||||
*/
|
||||
public static Bitmap bytesToBitmap( byte[] b, BitmapFactory.Options options ) {
|
||||
if ( b.length != 0 ) {
|
||||
return BitmapFactory.decodeByteArray( b, 0, b.length, options );
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get max supported image size which will differ from different devices.
|
||||
*
|
||||
* @return max size related to the device.
|
||||
*/
|
||||
public static int getMaxSupportedImageSize() {
|
||||
int textureLimit = getMaxTextureSize();
|
||||
if ( textureLimit == 0 ) {
|
||||
return SIZE_DEFAULT;
|
||||
} else {
|
||||
return Math.min( textureLimit, SIZE_LIMIT );
|
||||
}
|
||||
}
|
||||
|
||||
public static int getMaxTextureSize2() {
|
||||
// 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];
|
||||
}
|
||||
|
||||
/**
|
||||
* Decode a bitmap's input stream to find a proper inSampleSize according to device's max supported size.
|
||||
*
|
||||
* @param is bitmap's data source
|
||||
* @param close whether to close input stream after work is done.
|
||||
* @return a proper inSampleSize
|
||||
*/
|
||||
public static int findProperInSampleSize( InputStream is, boolean close ) {
|
||||
// Just decode image size into options
|
||||
BitmapFactory.Options options = new BitmapFactory.Options();
|
||||
options.inJustDecodeBounds = true;
|
||||
|
||||
try {
|
||||
BitmapFactory.decodeStream( is, null, options );
|
||||
} catch ( Exception e ) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
if ( close ) IOUtils.closeSilently( is );
|
||||
}
|
||||
|
||||
int maxSize = getMaxSupportedImageSize();
|
||||
int sampleSize = 1;
|
||||
|
||||
while ( options.outHeight / sampleSize > maxSize || options.outWidth / sampleSize > maxSize ) {
|
||||
sampleSize = sampleSize << 1;
|
||||
}
|
||||
|
||||
Log.i( TAG, "sample size is " + sampleSize );
|
||||
return sampleSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read a picture's degree from a file.
|
||||
*
|
||||
* @param file data source of a picture
|
||||
* @return degrees range from 0 to 360
|
||||
*/
|
||||
public static int readPictureDegree( File file ) {
|
||||
return readPictureDegree( file.getAbsolutePath() );
|
||||
}
|
||||
|
||||
/**
|
||||
* Read a picture's degree from a file, we use {@link ExifInterface} instead of {@link android.media.ExifInterface}
|
||||
* to avoid some unexpected bugs.
|
||||
*
|
||||
* @param filePath file's absolute path which we can read data source of a picture from.
|
||||
* @return degrees range from 0 to 360
|
||||
*/
|
||||
public static int readPictureDegree( String filePath ) {
|
||||
int degree = 0;
|
||||
|
||||
try {
|
||||
ExifInterface exifInterface = new ExifInterface( filePath );
|
||||
int orientation = exifInterface.getAttributeInt( ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL );
|
||||
switch ( orientation ) {
|
||||
case ExifInterface.ORIENTATION_ROTATE_90:
|
||||
degree = 90;
|
||||
break;
|
||||
case ExifInterface.ORIENTATION_ROTATE_180:
|
||||
degree = 180;
|
||||
break;
|
||||
case ExifInterface.ORIENTATION_ROTATE_270:
|
||||
degree = 270;
|
||||
break;
|
||||
}
|
||||
} catch ( Exception e ) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
Log.i( TAG, "ExifInterface, degree is " + degree );
|
||||
|
||||
return degree;
|
||||
}
|
||||
|
||||
/**
|
||||
* Rotate an bitmap to a specific angle.
|
||||
*
|
||||
* @param angle target angle
|
||||
* @param bitmap data source
|
||||
* @return Returns an immutable bitmap from subset of the source bitmap,
|
||||
* transformed by the optional matrix. The new bitmap may be the
|
||||
* same object as source, or a copy may have been made. It is
|
||||
* initialized with the same density as the original bitmap.
|
||||
* <p>
|
||||
* If the source bitmap is immutable and the requested subset is the
|
||||
* same as the source bitmap itself, then the source bitmap is
|
||||
* returned and no new bitmap is created.
|
||||
*/
|
||||
public static Bitmap rotateBitmap( int angle, Bitmap bitmap ) {
|
||||
if ( bitmap == null ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
int width = bitmap.getWidth();
|
||||
int height = bitmap.getHeight();
|
||||
Matrix matrix = new Matrix();
|
||||
matrix.preRotate( angle );
|
||||
return Bitmap.createBitmap( bitmap, 0, 0, width, height, matrix, true );
|
||||
} catch ( Exception e ) {
|
||||
e.printStackTrace();
|
||||
return bitmap;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get picture's absolute path according to its uri.
|
||||
*
|
||||
* @param context context
|
||||
* @param uri picture's uri
|
||||
* @return absolute path of uri.
|
||||
*/
|
||||
public static String getRealPathFromUri( Context context, Uri uri ) {
|
||||
int sdkVersion = Build.VERSION.SDK_INT;
|
||||
if ( sdkVersion >= 19 ) {
|
||||
return getRealPathFromUriAboveApi19( context, uri );
|
||||
} else {
|
||||
return getRealPathFromUriBelowAPI19( context, uri );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a default {@link BitmapFactory.Options} .
|
||||
* Note this options use rgb_565 and a proper inSampleSize in order to save memory.
|
||||
*
|
||||
* @param is data source of picture
|
||||
* @param close whether to close data source
|
||||
* @return options containing rgb_565 config and a proper inSampleSize.
|
||||
*/
|
||||
public static BitmapFactory.Options newDefaultOptions( InputStream is, boolean close ) {
|
||||
final BitmapFactory.Options options = new BitmapFactory.Options();
|
||||
options.inPreferredConfig = Bitmap.Config.RGB_565;
|
||||
options.inSampleSize = BitmapHelper.findProperInSampleSize( is, close );
|
||||
|
||||
return options;
|
||||
}
|
||||
|
||||
/**
|
||||
* Save picture to local file.
|
||||
*
|
||||
* @param bitmap data source
|
||||
* @param file local file to store picture.
|
||||
*/
|
||||
public static void savePicture( Bitmap bitmap, File file ) {
|
||||
final long start = System.currentTimeMillis();
|
||||
|
||||
if ( bitmap == null || file == null ) {
|
||||
Log.i( TAG, "保存失败, bitmap or file is null." );
|
||||
return;
|
||||
}
|
||||
if ( file.getParentFile() != null && !file.getParentFile().exists() ) {
|
||||
file.getParentFile().mkdirs();
|
||||
}
|
||||
|
||||
try {
|
||||
final FileOutputStream fos = new FileOutputStream( file );
|
||||
bitmap.compress( Bitmap.CompressFormat.JPEG, 100, fos );
|
||||
fos.flush();
|
||||
fos.close();
|
||||
|
||||
if ( file.exists() ) {
|
||||
Log.i( TAG, "保存成功" );
|
||||
}
|
||||
} catch ( Exception e ) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
Log.i( TAG, "saving picture costs " + ( System.currentTimeMillis() - start ) + "ms" );
|
||||
}
|
||||
|
||||
/**
|
||||
* 适配api19以下(不包括api19),根据uri获取图片的绝对路径
|
||||
*
|
||||
* @param context 上下文对象
|
||||
* @param uri 图片的Uri
|
||||
* @return 如果Uri对应的图片存在, 那么返回该图片的绝对路径, 否则返回null
|
||||
*/
|
||||
private static String getRealPathFromUriBelowAPI19( Context context, Uri uri ) {
|
||||
return getDataColumn( context, uri, null, null );
|
||||
}
|
||||
|
||||
/**
|
||||
* 适配api19及以上,根据uri获取图片的绝对路径
|
||||
*
|
||||
* @param context 上下文对象
|
||||
* @param uri 图片的Uri
|
||||
* @return 如果Uri对应的图片存在, 那么返回该图片的绝对路径, 否则返回null
|
||||
*/
|
||||
@SuppressLint( "NewApi" )
|
||||
private static String getRealPathFromUriAboveApi19( Context context, Uri uri ) {
|
||||
String filePath = null;
|
||||
|
||||
try {
|
||||
// 如果是document类型的 uri, 则通过document id来进行处理
|
||||
if ( DocumentsContract.isDocumentUri( context, uri ) ) {
|
||||
String documentId = DocumentsContract.getDocumentId( uri );
|
||||
if ( isMediaDocument( uri ) ) {
|
||||
// 使用':'分割
|
||||
String id = documentId.split( ":" )[1];
|
||||
String selection = MediaStore.Images.Media._ID + "=?";
|
||||
String[] selectionArgs = {id};
|
||||
filePath = getDataColumn( context, MediaStore.Images.Media.EXTERNAL_CONTENT_URI, selection, selectionArgs );
|
||||
} else if ( isDownloadsDocument( uri ) ) {
|
||||
Uri contentUri = ContentUris.withAppendedId( Uri.parse( "content://downloads/public_downloads" ), Long.valueOf( documentId ) );
|
||||
filePath = getDataColumn( context, contentUri, null, null );
|
||||
}
|
||||
} else if ( "content".equalsIgnoreCase( uri.getScheme() ) ) {
|
||||
filePath = getDataColumn( context, uri, null, null );
|
||||
} else if ( "file".equals( uri.getScheme() ) ) {
|
||||
filePath = uri.getPath();
|
||||
}
|
||||
} catch ( Exception e ) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
return filePath;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取数据库表中的 _data 列,即返回Uri对应的文件路径
|
||||
*/
|
||||
private static String getDataColumn( Context context, Uri uri, String selection, String[] selectionArgs ) {
|
||||
String path = null;
|
||||
String[] projection = new String[]{MediaStore.Images.Media.DATA};
|
||||
Cursor cursor = null;
|
||||
|
||||
try {
|
||||
cursor = context.getContentResolver().query( uri, projection, selection, selectionArgs, null );
|
||||
|
||||
if ( cursor != null && cursor.moveToFirst() ) {
|
||||
int columnIndex = cursor.getColumnIndexOrThrow( projection[0] );
|
||||
path = cursor.getString( columnIndex );
|
||||
}
|
||||
} catch ( Exception e ) {
|
||||
if ( cursor != null ) {
|
||||
cursor.close();
|
||||
cursor = null;
|
||||
}
|
||||
} finally {
|
||||
if ( cursor != null ) {
|
||||
cursor.close();
|
||||
cursor = null;
|
||||
}
|
||||
}
|
||||
|
||||
return path;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param uri the Uri to check
|
||||
* @return Whether the Uri authority is MediaProvider
|
||||
*/
|
||||
private static boolean isMediaDocument( Uri uri ) {
|
||||
return "com.android.providers.media.documents".equals( uri.getAuthority() );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param uri the Uri to check
|
||||
* @return Whether the Uri authority is DownloadsProvider
|
||||
*/
|
||||
private static boolean isDownloadsDocument( Uri uri ) {
|
||||
return "com.android.providers.downloads.documents".equals( uri.getAuthority() );
|
||||
}
|
||||
|
||||
public static int getMaxTextureSize() {
|
||||
try {
|
||||
// Safe minimum default size
|
||||
final int IMAGE_MAX_BITMAP_DIMENSION = SIZE_DEFAULT;
|
||||
|
||||
// Get EGL Display
|
||||
EGL10 egl = ( EGL10 ) EGLContext.getEGL();
|
||||
EGLDisplay display = egl.eglGetDisplay( EGL10.EGL_DEFAULT_DISPLAY );
|
||||
|
||||
// Initialise
|
||||
int[] version = new int[2];
|
||||
egl.eglInitialize( display, version );
|
||||
|
||||
// Query total number of configurations
|
||||
int[] totalConfigurations = new int[1];
|
||||
egl.eglGetConfigs( display, null, 0, totalConfigurations );
|
||||
|
||||
// Query actual list configurations
|
||||
EGLConfig[] configurationsList = new EGLConfig[totalConfigurations[0]];
|
||||
egl.eglGetConfigs( display, configurationsList, totalConfigurations[0], totalConfigurations );
|
||||
|
||||
int[] textureSize = new int[1];
|
||||
int maximumTextureSize = 0;
|
||||
|
||||
// Iterate through all the configurations to located the maximum texture size
|
||||
for ( int i = 0; i < totalConfigurations[0]; i++ ) {
|
||||
// Only need to check for width since opengl textures are always squared
|
||||
egl.eglGetConfigAttrib( display, configurationsList[i], EGL10.EGL_MAX_PBUFFER_WIDTH, textureSize );
|
||||
|
||||
// Keep trackCustomEvent of the maximum texture size
|
||||
if ( maximumTextureSize < textureSize[0] )
|
||||
maximumTextureSize = textureSize[0];
|
||||
}
|
||||
|
||||
// Release
|
||||
egl.eglTerminate( display );
|
||||
|
||||
// Return largest texture size found, or default
|
||||
return Math.max( maximumTextureSize, IMAGE_MAX_BITMAP_DIMENSION );
|
||||
} catch ( Exception e ) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
public static String bitmapToBase64( Bitmap bitmap ) {
|
||||
String result = null;
|
||||
try {
|
||||
if ( bitmap != null ) {
|
||||
result = Base64.encodeToString( bitmapToBytes( bitmap ), Base64.DEFAULT );
|
||||
}
|
||||
} catch ( Exception e ) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public static Bitmap base64ToBitmap( String base64Data ) {
|
||||
byte[] bytes = Base64.decode( base64Data, Base64.DEFAULT );
|
||||
return BitmapFactory.decodeByteArray( bytes, 0, bytes.length );
|
||||
}
|
||||
|
||||
/**
|
||||
* 在系统返回的intent中获取图片信息,并转化为uri
|
||||
*
|
||||
* @param data
|
||||
* @return
|
||||
*/
|
||||
public static Uri convertUri( Context context, Intent data ) {
|
||||
if ( data == null || data.getData() == null ) {
|
||||
return null;
|
||||
}
|
||||
Uri localUri = data.getData();
|
||||
String scheme = localUri.getScheme();
|
||||
String imagePath = "";
|
||||
if ( "content".equals( scheme ) ) {
|
||||
String[] filePathColumns = {MediaStore.Images.Media.DATA};
|
||||
Cursor c = context.getContentResolver().query( localUri, filePathColumns, null, null, null );
|
||||
if ( c != null ) {
|
||||
c.moveToFirst();
|
||||
int columnIndex = c.getColumnIndex( filePathColumns[0] );
|
||||
imagePath = c.getString( columnIndex );
|
||||
c.close();
|
||||
}
|
||||
} else if ( "file".equals( scheme ) ) {//小米4选择云相册中的图片是根据此方法获得路径
|
||||
imagePath = localUri.getPath();
|
||||
}
|
||||
if ( TextUtils.isEmpty( imagePath ) ) {
|
||||
return localUri;
|
||||
}
|
||||
Uri uri = Uri.fromFile( new File( imagePath ) );
|
||||
return uri != null ? uri : localUri;
|
||||
}
|
||||
|
||||
public static Bitmap colorToBitmap( Context context, int colorResId ) {// drawable 转换成bitmap
|
||||
Bitmap.Config config = Bitmap.Config.ARGB_8888;// 取drawable的颜色格式
|
||||
Bitmap bitmap = Bitmap.createBitmap( 1, 1, config );// 建立对应bitmap
|
||||
bitmap.eraseColor( context.getResources().getColor( colorResId ) );
|
||||
return bitmap;
|
||||
}
|
||||
|
||||
public static String getAlphaHexValue( float alpha ) {
|
||||
String color = Integer.toHexString( ( int ) alpha * 255 );
|
||||
return TextUtils.isEmpty( color ) ? color : color.toUpperCase();
|
||||
}
|
||||
|
||||
/**
|
||||
* 抓取本地视频缩略图(操作可能耗时,尽量异步进行)
|
||||
*
|
||||
* @param filePath
|
||||
* @return
|
||||
*/
|
||||
public static Bitmap getVideoThumbnail( String filePath ) {
|
||||
Bitmap b = null;
|
||||
MediaMetadataRetriever retriever = new MediaMetadataRetriever();
|
||||
try {
|
||||
retriever.setDataSource( filePath );
|
||||
b = retriever.getFrameAtTime();
|
||||
} catch ( IllegalArgumentException e ) {
|
||||
e.printStackTrace();
|
||||
} catch ( RuntimeException e ) {
|
||||
e.printStackTrace();
|
||||
|
||||
} finally {
|
||||
try {
|
||||
retriever.release();
|
||||
} catch ( RuntimeException e ) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
return b;
|
||||
}
|
||||
|
||||
public interface OnCompressListener {
|
||||
|
||||
void onCompressSuccess( byte[] data );
|
||||
|
||||
void onCompressFailed( String msg );
|
||||
|
||||
void onBeforeCompress();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user