Android仿微信图片编辑处理:文字,马赛克,裁剪,涂鸦,旋转图片等
16lz
2021-01-25
Android仿微信图片编辑处理:文字,马赛克,裁剪,涂鸦,旋转图片等
如图:
这个项目实现了微信图片编辑处理的关键功能,如给一张图片添加文字,打上马赛克,裁剪图片,在图片上手势涂鸦。引用了kareluo的Imaging库,但是kareluo的Imaging库示例代码有两个遗留问题需要重新解决:
1,它是用kotlin写的,我重新把kotlin代码部分用Java写了一遍。
2,kareluo的Imaging库中,编辑图片的IMGEditActivity接受两种传入的资源路径类型:asset和file。Android 4.4以下可以直接获取再拼装。但在高版本(大于4.4,API19)就不好办,且在大于4.4版本的机器上,用相册选择器选中的图片资源是以content://开头表示的,这需要把content://这样的路径重新转为file传过去。
我把上述两个问题解决后写了简单的测试:
package zhangphil.app;import android.annotation.TargetApi;import android.content.ContentResolver;import android.content.ContentUris;import android.content.Context;import android.content.Intent;import android.database.Cursor;import android.graphics.Bitmap;import android.net.Uri;import android.os.Build;import android.os.Environment;import android.provider.DocumentsContract;import android.provider.MediaStore;import android.support.v7.app.AppCompatActivity;import android.os.Bundle;import android.view.View;import java.io.File;import me.kareluo.imaging.IMGEditActivity;public class MainActivity extends AppCompatActivity { public static final int REQ_SELECT_PHOTO = 0xf0a; private Bitmap avatarBitMap = null; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); findViewById(R.id.button).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { seleteImg(); } }); } private void seleteImg() { Intent intent = new Intent(); intent.setType("image/*"); intent.setAction(Intent.ACTION_GET_CONTENT); startActivityForResult(intent, REQ_SELECT_PHOTO); } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { switch (requestCode) { case REQ_SELECT_PHOTO: { // 选取照片。 if (resultCode == RESULT_OK && data != null) { try { avatarBitMap = MediaStore.Images.Media.getBitmap(this.getContentResolver(), data.getData()); //此处获得了Bitmap图片,可以用作设置头像等等。 } catch (Exception e) { e.printStackTrace(); } Intent intent = new Intent(this, IMGEditActivity.class); try { String uri_path = getFilePathByUri(this, data.getData()); Uri uri = Uri.fromFile(new File(uri_path)); System.out.println(uri.toString()); intent.putExtra(IMGEditActivity.EXTRA_IMAGE_URI, uri); //intent.putExtra(IMGEditActivity.EXTRA_IMAGE_SAVE_PATH,); startActivity(intent); } catch (Exception e) { e.printStackTrace(); } } break; } default: break; } } @TargetApi(19) public static String getFilePathByUri(Context context, Uri uri) { String path = null; // 以 file:// 开头的 if (ContentResolver.SCHEME_FILE.equals(uri.getScheme())) { path = uri.getPath(); return path; } // 以 content:// 开头的,比如 content://media/extenral/images/media/17766 if (ContentResolver.SCHEME_CONTENT.equals(uri.getScheme()) && Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) { Cursor cursor = context.getContentResolver().query(uri, new String[]{MediaStore.Images.Media.DATA}, null, null, null); if (cursor != null) { if (cursor.moveToFirst()) { int columnIndex = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA); if (columnIndex > -1) { path = cursor.getString(columnIndex); } } cursor.close(); } return path; } // 4.4及之后的 是以 content:// 开头的,比如 content://com.android.providers.media.documents/document/image%3A235700 if (ContentResolver.SCHEME_CONTENT.equals(uri.getScheme()) && Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { if (DocumentsContract.isDocumentUri(context, uri)) { if (isExternalStorageDocument(uri)) { // ExternalStorageProvider final String docId = DocumentsContract.getDocumentId(uri); final String[] split = docId.split(":"); final String type = split[0]; if ("primary".equalsIgnoreCase(type)) { path = Environment.getExternalStorageDirectory() + "/" + split[1]; return path; } } else if (isDownloadsDocument(uri)) { // DownloadsProvider final String id = DocumentsContract.getDocumentId(uri); final Uri contentUri = ContentUris.withAppendedId(Uri.parse("content://downloads/public_downloads"), Long.valueOf(id)); path = getDataColumn(context, contentUri, null, null); return path; } else if (isMediaDocument(uri)) { // MediaProvider final String docId = DocumentsContract.getDocumentId(uri); final String[] split = docId.split(":"); final String type = split[0]; Uri contentUri = null; if ("image".equals(type)) { contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI; } else if ("video".equals(type)) { contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI; } else if ("audio".equals(type)) { contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI; } final String selection = "_id=?"; final String[] selectionArgs = new String[]{split[1]}; path = getDataColumn(context, contentUri, selection, selectionArgs); return path; } } } return null; } public static String getDataColumn(Context context, Uri uri, String selection, String[] selectionArgs) { Cursor cursor = null; String column = MediaStore.Images.Media.DATA; String[] projection = {column}; try { cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs, null); if (cursor != null && cursor.moveToFirst()) { int index = cursor.getColumnIndexOrThrow(column); return cursor.getString(index); } } finally { if (cursor != null) cursor.close(); } return null; } /** * @param uri The Uri to check. * @return Whether the Uri authority is ExternalStorageProvider. */ public static boolean isExternalStorageDocument(Uri uri) { return "com.android.externalstorage.documents".equals(uri.getAuthority()); } /** * @param uri The Uri to check. * @return Whether the Uri authority is DownloadsProvider. */ public static boolean isDownloadsDocument(Uri uri) { return "com.android.providers.downloads.documents".equals(uri.getAuthority()); } /** * @param uri The Uri to check. * @return Whether the Uri authority is MediaProvider. */ public 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 Google Photos. */ public static boolean isGooglePhotosUri(Uri uri) { return "com.google.android.apps.photos.content".equals(uri.getAuthority()); }}
亲测在Android8.0上正常。
完整可运行的项目已经整理出来,上传到github:https://github.com/zhangphil/WeiXinPictureTool
更多相关文章
- android 背景图片滚动
- android加载大图推荐框架LargeImageView及所遇问题——部分机型
- TextView(文本框)详解
- Android(安卓)OOM 排查与解决——图片加载优化
- APP瘦身这一篇就够了
- 【Android】Android实现自定义带文字和图片的Button
- [置顶] 我的Android进阶之旅------>Android疯狂连连看游戏的实现
- ffmpeg 移植到 android 并使用
- Android(安卓)图片Bitmap保存到内存卡