如何在Yalantis UCrop中加载指定图片而非从相册选择
安卓UCrop裁剪:用已知Uri/Bitmap替代相册选择逻辑
我正在开发一款安卓计时管理应用,需对图片执行OCR识别,希望先通过Yalantis UCrop裁剪图片。目前已选定目标图片,可获取其相关信息,但现有代码需从相册选择图片,且裁剪后的Uri经过修改,无法获取所需的原图信息。请问如何使用已知的Uri或Bitmap替代代码中mGetContent.launch("image/*")的相册选择逻辑?
现有主Activity代码
ActivityResultLauncher<String> mGetContent; @Override protected void onCreate(Bundle savedInstanceState) { ActivityResultLauncher<String> mGetContent=registerForActivityResult(new ActivityResultContracts.GetContent(), result -> { Intent intent= new Intent(this, CropperActivity.class); intent.putExtra("DATA", result.toString()); startActivityForResult(intent, 101); }); mGetContent.launch("image/*"); } @Override protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { super.onActivityResult(requestCode, resultCode, data); Log.v("onActivityResult", "requestCode: " + requestCode); Log.v("onActivityResult", "resultCode: " + resultCode); if (requestCode == 101 && resultCode == -1 && data != null) { Uri selectedImage = data.getData(); imgCap.setImageURI(selectedImage); //getOCR(selectedImage.toString()); } else { Log.e("capture error", "error: no image!!!!!!!"); } }
CropperActivity代码
import android.content.Intent; import android.net.Uri; import android.os.Bundle; import androidx.annotation.Nullable; import androidx.appcompat.app.AppCompatActivity; import com.yalantis.ucrop.UCrop; import com.yalantis.ucrop.model.AspectRatio; import java.io.File; import java.util.UUID; public class CropperActivity extends AppCompatActivity { String result; Uri fileUri; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.v_cropper); readIntent(); String dest_uri= UUID.randomUUID().toString() + ".jpg"; UCrop.Options options=new UCrop.Options(); options.setAspectRatioOptions(3, new AspectRatio("1:1", 1, 1), new AspectRatio("2:1", 2, 1), new AspectRatio("3:1", 3, 1), new AspectRatio("5:1", 5, 1), new AspectRatio("8:1", 8, 1), new AspectRatio("10:1", 10, 1)); UCrop.of(fileUri, Uri.fromFile(new File(getCacheDir(),dest_uri))) .withOptions(options) .withMaxResultSize(2000,2000) .start(CropperActivity.this); } private void readIntent() { Intent intent=getIntent(); if(intent.getExtras()!=null) { result=intent.getStringExtra("DATA"); fileUri=Uri.parse(result); } } @Override protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { super.onActivityResult(requestCode, resultCode, data); if(resultCode==RESULT_OK && requestCode==UCrop.REQUEST_CROP){ final Uri resultURI=UCrop.getOutput(data); Intent returnIntent=new Intent(); returnIntent.putExtra("RESULT", String.valueOf(resultURI)); setResult(-1, returnIntent); finish(); } else if(resultCode==UCrop.RESULT_ERROR) { final Throwable cropError=UCrop.getError(data); } } }
解决方案
一、直接使用已知Uri启动裁剪
完全移除相册选择相关的ActivityResultLauncher代码,直接将已知Uri传入CropperActivity:
修改主Activity的onCreate方法:
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.你的主布局); // 确保设置了布局 // 替换为你已获取到的目标图片Uri Uri targetImageUri = ...; // 示例:Uri.parse("content://media/external/images/media/123") 或本地文件Uri // 直接启动裁剪页面 Intent intent = new Intent(this, CropperActivity.class); intent.putExtra("DATA", targetImageUri.toString()); startActivityForResult(intent, 101); }
二、使用Bitmap生成Uri后启动裁剪
如果只有Bitmap对象,先将Bitmap保存到应用缓存目录生成Uri,再传入CropperActivity:
- 添加Bitmap转Uri的工具方法:
private Uri bitmapToUri(Bitmap bitmap) { // 将Bitmap保存到缓存文件 File cacheFile = new File(getCacheDir(), "temp_image_" + System.currentTimeMillis() + ".jpg"); try (FileOutputStream fos = new FileOutputStream(cacheFile)) { bitmap.compress(Bitmap.CompressFormat.JPEG, 90, fos); fos.flush(); } catch (IOException e) { e.printStackTrace(); return null; } // Android 7.0+用FileProvider避免FileUriExposedException return FileProvider.getUriForFile(this, getPackageName() + ".fileprovider", cacheFile); }
- 在
onCreate中调用方法并启动裁剪:
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.你的主布局); // 替换为你已获取到的Bitmap Bitmap targetBitmap = ...; Uri bitmapUri = bitmapToUri(targetBitmap); if (bitmapUri != null) { Intent intent = new Intent(this, CropperActivity.class); intent.putExtra("DATA", bitmapUri.toString()); startActivityForResult(intent, 101); } else { Log.e("BitmapError", "Bitmap转Uri失败"); } }
注意事项
- 若使用FileProvider,需在
AndroidManifest.xml中注册:
<provider android:name="androidx.core.content.FileProvider" android:authorities="${applicationId}.fileprovider" android:exported="false" android:grantUriPermissions="true"> <meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/file_paths" /> </provider>
- 在
res/xml目录下创建file_paths.xml:
<?xml version="1.0" encoding="utf-8"?> <paths xmlns:android="http://schemas.android.com/apk/res/android"> <cache-path name="cache_images" path="/" /> </paths>
内容的提问来源于stack exchange,提问作者Nuggzy
相关产品推荐
相关产品推荐

