拍摄后的图片处理

Posted

技术标签:

【中文标题】拍摄后的图片处理【英文标题】:Picture manipulation after capture 【发布时间】:2015-04-19 19:24:54 【问题描述】:

如果您足够友善,我需要您的帮助来解决我在使用 android 应用时遇到的问题:

我已经设法在我的 MainActivity 中捕获了一张图片并将其显示到一个单独的活动中 - PictureActivity。我的代码如下:

在我的 MainActivity 我有

private static final int CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE = 100;

/**
 * This is called in tap on a graphic element in my MainActivity layout
 */
public void launchCamera(View v) 
        Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        startActivityForResult(intent, CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE);
    

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) 
        if (requestCode == CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE) 
            Bitmap imageData = null;

            if (resultCode == RESULT_OK) 
                imageData = (Bitmap) data.getExtras().get("data");

                Intent i = new Intent(this, PictureActivity.class);
                i.putExtra("captured_picture", imageData);
                startActivity(i);
             else if (resultCode == RESULT_CANCELED) 
                // User cancelled the image capture
             else 
                Toast.makeText(getApplicationContext(), R.string.picture_capture_error, Toast.LENGTH_SHORT).show();
            
        
    

我的 PictureActivity 如下所示:

public class PictureActivity extends ActionBarActivity 

    @Override
    protected void onCreate(Bundle savedInstanceState) 
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_picture);

        Bitmap bitmap  = getIntent().getExtras().getParcelable("captured_picture");

        ImageView view = (ImageView) findViewById(R.id.preview_photo);
        view.setImageBitmap(bitmap);
    


    @Override
    public boolean onCreateOptionsMenu(Menu menu) 
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.image_menu, menu);
        return true;
    

    @Override
    public boolean onOptionsItemSelected(MenuItem item) 
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();


        return super.onOptionsItemSelected(item);
    

我的 PictureActivity 布局看起来像这样

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_
    android:layout_>

    <ImageView
        android:id="@+id/preview_photo"
        android:layout_
        android:layout_ />
</LinearLayout>

这是目前为止的最终结果:

长话短说,接下来是我想做的事情

如果用户点击主操作栏中的中间按钮,则旋转图片 如果用户点击左起第一个按钮,则裁剪图片

接下来,将图像保存在某处(可能是在共享首选项或会话中?),然后,将其上传到远程服务器。我说“将图像保存在某处”是因为用户可以选择拍摄第二张照片(最多两张)并在上面执行相同的操作(通过点击第一个按钮从右侧开始,在主操作栏中)。

到目前为止,我无法弄清楚的是:

我如何知道当前图像(我在屏幕上看到的)是什么 在将其上传到远程服务器之前,如何设置它的名称和保存位置 当我点击两个按钮之一(croprotate)时,如何操作它

抱歉发了这么长的帖子,提前感谢您的帮助!

【问题讨论】:

【参考方案1】:

回答您的 3 个问题:

    您看到的当前图像在您的设备 RAM 中。它是保存数据的位图对象。 您必须将位图保存到您的设备存储中 您必须先转换位图,然后再将其保存到存储中

这里有一些可能对你有帮助的代码:

public static void saveBitmapToFile(Bitmap bitmap, String filename)
        FileOutputStream out = null;
        try 
            out = new FileOutputStream(filename);
            bitmap.compress(Bitmap.CompressFormat.PNG, 100, out); // bmp is your Bitmap instance
            // PNG is a lossless format, the compression factor (100) is ignored 
         catch (Exception e) 
            e.printStackTrace();
         finally 
            try 
                if (out != null) 
                    out.close();
                
             catch (IOException e) 
                e.printStackTrace();
            
        
    

public static Bitmap cropAndRotateBitmap(Bitmap bitmap, Rect cropRect, int rotateByDegrees) 
        Log.v(TAG, "cropAndRotateBitmap()");
        Log.v(TAG, "bitmap: " + bitmap);
        //Log.v(TAG, "orientation: " + orientation);
        Log.v(TAG, "degrees: " + rotateByDegrees);
        Log.v(TAG, "cropRect: " + cropRect);
        int cropRectWidth = cropRect.right - cropRect.left;
        int cropRectHeight = cropRect.bottom - cropRect.top;

        System.gc();

        Bitmap result;
        Matrix m = new Matrix();
        Canvas canvas = new Canvas();
        if (rotateByDegrees == 0) 
            result = Bitmap.createBitmap(cropRectWidth, cropRectHeight, Bitmap.Config.ARGB_8888);
            canvas = new Canvas(result);
            m.postTranslate(-cropRect.left, -cropRect.top);

         else if (rotateByDegrees == 90) 
            Log.v(TAG, "rotate 90, cropRect: " + cropRect);
            result = Bitmap.createBitmap(cropRectHeight, cropRectWidth, Bitmap.Config.ARGB_8888);
            canvas = new Canvas(result);
            m.postTranslate(-cropRect.left, -cropRect.height() - cropRect.top);
            m.postRotate(90);

         else if (rotateByDegrees == 180) 
            Log.v(TAG, "rotate 180");
            result = Bitmap.createBitmap(cropRectWidth, cropRectHeight, Bitmap.Config.ARGB_8888);
            canvas = new Canvas(result);
            m.postTranslate(-cropRect.left - cropRect.width(), -cropRect.height() - cropRect.top);
            m.postRotate(180);

         else  // 270
            Log.v(TAG, "rotate 270");
            result = Bitmap.createBitmap(cropRectHeight, cropRectWidth, Bitmap.Config.ARGB_8888);
            canvas = new Canvas(result);
            m.postTranslate(-cropRect.width() - cropRect.left, -cropRect.top);
            m.postRotate(270);

        
        Paint whitePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        whitePaint.setStyle(Paint.Style.FILL);
        whitePaint.setColor(Color.WHITE);

        canvas.drawBitmap(bitmap, m, whitePaint);
        // canvas.restore();
        return result;
    

    public static Bitmap rotateBitmap(Bitmap bitmap, int rotateByDegrees) 

        Log.v(TAG, "rotateBitmap()");
        Log.v(TAG, "degrees: " + rotateByDegrees);

        System.gc();

        Bitmap result;
        Canvas canvas = new Canvas();
        if (rotateByDegrees == 0) 
            result = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), Bitmap.Config.ARGB_8888);
            canvas = new Canvas(result);
            canvas.save();
         else if (rotateByDegrees == 90) 
            result = Bitmap.createBitmap(bitmap.getHeight(), bitmap.getWidth(), Bitmap.Config.ARGB_8888);
            canvas = new Canvas(result);
            canvas.save();
            canvas.rotate(90);
            canvas.translate(0, -1 * bitmap.getHeight());
         else if (rotateByDegrees == 180) 
            result = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), Bitmap.Config.ARGB_8888);
            canvas = new Canvas(result);
            canvas.save();
            canvas.rotate(180);
            canvas.translate(-1 * bitmap.getWidth(), -1 * bitmap.getHeight());
         else  // 270
            result = Bitmap.createBitmap(bitmap.getHeight(), bitmap.getWidth(), Bitmap.Config.ARGB_8888);
            canvas = new Canvas(result);
            canvas.save();
            canvas.rotate(270);
            canvas.translate(-1 * bitmap.getWidth(), 0);
        

        canvas.drawBitmap(bitmap, new Matrix(), null);
        canvas.restore();
        return result;
    

【讨论】:

以上是关于拍摄后的图片处理的主要内容,如果未能解决你的问题,请参考以下文章

证件照(1寸2寸)拍摄处理知识汇总 此博文包含图片

VB 处理扫描类型的tif图片时保存时出现灰色图

摄像头拍摄后对图片进行图像处理-python(空域增强)

为啥微信小程序拍摄图片信息异常

OpenCV|图片与视频的相互转换(C++&Python)

KindEditor的简单使用,以及上传图片预览图片,用户删除图片后的数据处理(重点)