Android:在捕获或从图库中挑选后裁剪图像

Posted

技术标签:

【中文标题】Android:在捕获或从图库中挑选后裁剪图像【英文标题】:Android: Cropping an image after capture or picking from Gallery 【发布时间】:2017-01-22 19:14:50 【问题描述】:

我正在开发一个应用程序,作为其中的一部分,我需要在从相机捕获或从图库中挑选图像后裁剪图像。我的应用程序中有一个导航抽屉,用户可以从中选择一个选项来查看他的图像(相机或画廊)。每当他单击其中一个选项时,将调用一个片段,其余部分在其中完成(调用相机,单击图片,获取数据并将图像设置为图像视图)。所以,现在我需要为图像添加裁剪功能,并且我使用了在线提供的裁剪库之一,可以找到 here。在我的应用程序中尝试之前,我创建了一个新的 android studio 项目并制作了一个示例应用程序,用户可以在其中通过单击按钮选择相机,然后完成裁剪并将裁剪后的图像设置为屏幕上的图像视图。该项目可以找到here。现在,我尝试在我的应用程序中实现相同的功能,但它不起作用。来到代码,我有一个导航抽屉类,然后是一个片段类。在我的 MainDrawerActivity 中(简要):

在菜单选项中:

if (id == R.id.nav_camera)  
        Fragment_TouchImageView camFrag = (Fragment_TouchImageView) getSupportFragmentManager().findFragmentById(R.id.imageFragment);
        camFrag.startCamera();
    
else if (id == R.id.nav_gallery)  
        Fragment_TouchImageView galFrag = (Fragment_TouchImageView) getSupportFragmentManager().findFragmentById(R.id.imageFragment);
        galFrag.openGallery();
    

现在,在我的 Fragment_TouchImageView.java(片段)中:

这是完整的代码:

package com.example.shravan.watershed;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.provider.MediaStore;
import android.support.v4.app.Fragment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Toast;

import com.soundcloud.android.crop.Crop;

import java.io.File;

public class Fragment_TouchImageView extends Fragment 

Uri imageUri;
private TouchImageView myTVF;
static final int REQUEST_IMAGE_CAPTURE = 10;
static final int PICK_IMAGE = 100;
private static Context context;
private static final String TAG = "Arunachala";

public Fragment_TouchImageView() 
    // Required empty public constructor


@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) 
    View v = inflater.inflate(R.layout.fragment_fragment__touch_image_view, container, false);
    context= getActivity().getApplicationContext();
    myTVF = (TouchImageView) v.findViewById(R.id.img);
    myTVF.setImageBitmap(null);
    return v;


public void startCamera() 
    Intent i = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
    startActivityForResult(i, REQUEST_IMAGE_CAPTURE);


public void openGallery() 
    Intent gallery = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.INTERNAL_CONTENT_URI);
    startActivityForResult(gallery, PICK_IMAGE);


@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) 
    if (requestCode == REQUEST_IMAGE_CAPTURE && resultCode == Activity.RESULT_OK) 
        print("Camera requested");
        beginCrop(data.getData());
        print("Crop called and came to next line");
    
    else if (requestCode == PICK_IMAGE  && resultCode == Activity.RESULT_OK)           
        print("Gallery requested");
        beginCrop(data.getData());
        print("Crop called and came to next line");
    
    else if (requestCode == Crop.REQUEST_CROP) 
        print("Crop.REQUEST_CROP called");
        handleCrop(resultCode, data);
        print("handleCrop called and came to next line");
    


private void beginCrop(Uri source) 
    print("Crop has begun");
    Uri destination = Uri.fromFile(new File(context.getCacheDir(), "cropped"));
    Crop.of(source, destination).asSquare().start(getActivity());
    print("Crop has ended");


private void handleCrop(int resultCode, Intent result) 
    print("Came to handleCrop");
    if (resultCode == Activity.RESULT_OK) 
        print("RESULT OK");
        myTVF.setImageURI(Crop.getOutput(result));
     else if (resultCode == Crop.RESULT_ERROR) 
        Toast.makeText(getActivity(), Crop.getError(result).getMessage(), Toast.LENGTH_SHORT).show();
    


private void print(String s)
    Log.d(TAG, s);


所以,我给出了一系列日志标签来了解流程,这就是问题所在。每当我选择相机或画廊时,它都会正确打开,当我捕获图像时,将调用 beginCrop(),当我选择所需的裁剪区域并单击完成时,它什么也不做。流程不会进入这个循环:

else if (requestCode == Crop.REQUEST_CROP) 
        print("Crop.REQUEST_CROP called");
        handleCrop(resultCode, data);
        print("handleCrop called and came to next line");
    

在不同的示例应用程序项目中相同的工作没有任何问题。(它没有片段)

请帮我解决这个问题!

【问题讨论】:

我有同样的问题,因为 onActivityResult 在片段中没有被正确调用。所以使用另一个库或将片段更改为活动 @AntonKazakov 感谢您的回复。我无法将片段更改为活动,因为我需要在我的应用程序中使用片段。你能告诉我你的问题到底是什么吗?如果您遇到过类似的问题。您使用的是什么库? 稍等一下,发个答案 【参考方案1】:

几周前我在使用同一个库时遇到了同样的问题,所以问题出在 onActivityResult 及其在片段中使用它时的 requestCode 所以尝试以这种方式调用 Crop.of:

Crop.of(cropInputUri, cropOutputUri).asSquare().start(getContext(), Fragment.this, Crop.REQUEST_CROP);

【讨论】:

这是什么意思? "ACTUAL_VALUE_OF_LIBRARI_REQUEST_CODE" 我在哪里可以得到实际值? 我的意思是看看你期望什么值,看看实际值。然后将期望值放入 if 块 很抱歉没能找到你。我如何知道请求代码的值?有什么办法可以知道吗?请务必告诉我! 只记录两个值 我检查了它,发现它是 6709。我尝试过 else if (requestCode == 6709) 但仍然没有进入这个循环!可能出了什么问题?

以上是关于Android:在捕获或从图库中挑选后裁剪图像的主要内容,如果未能解决你的问题,请参考以下文章

刚从相机拍摄并通过从图库中挑选显示的Android裁剪图像

无法在android中裁剪图像

我如何在android中裁剪像scanmaster.apk这样的图像

具有多个选项的 Android 意图,即从图库中选择图像并使用前置摄像头捕获图像

Android - 如何从相机捕获图像或从库中添加

Android 从 Intent 获取裁剪图像的 URI