保存叠加图像[英] Saving Overlay Image

本文是小编为大家收集整理的关于保存叠加图像的处理/解决方法,可以参考本文帮助大家快速定位并解决问题,中文翻译不准确的可切换到English标签页查看源文。

问题描述

所以我正在寻找这个线程如何在图片上保存叠加. Android保存到JPG或PNG

我有我的代码拍照,并像该线程所建议的答案一样保存图像.问题是它只是覆盖着黑色背景.采取的实际图片不是图像的一部分.这是我的代码:

package com.commonsware.android.skeleton;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.Bitmap.CompressFormat;
import android.hardware.Camera;
import android.hardware.Camera.*;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import android.view.Display;
import android.view.Surface;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.widget.FrameLayout;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.List;

// ----------------------------------------------------------------------

public class SimpleBulbActivity extends Activity {
    private Preview mPreview;
    private static final String TAG = "CameraDemo";
    FrameLayout preview;
    Camera mCamera;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        // Hide the window title.
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        // create a File object for the parent directory
        File imageDirectory = new File(Environment.getExternalStorageDirectory() + "/SimpleBulb/");
        // Check if the directory exists
        if(!imageDirectory.exists()) {
            // have the object build the directory structure, if needed.
            imageDirectory.mkdirs();
        }
        setContentView(R.layout.main);
    }

    protected void onResume() {
        super.onResume();
        //Setup the FrameLayout with the Camera Preview Screen
        mPreview = new Preview(this);
        preview = (FrameLayout)findViewById(R.id.preview); 
        preview.addView(mPreview);
    }

    public void snap(View view) {
        mCamera.takePicture(shutterCallback, rawCallback, jpegCallback);
    }
    ShutterCallback shutterCallback = new ShutterCallback() {
      public void onShutter() {
          Log.d(TAG, "onShutter'd");
      }
    };

    PictureCallback rawCallback = new PictureCallback() {
      public void onPictureTaken(byte[] _data, Camera _camera) {
          Log.d(TAG, "onPictureTaken - raw");
      }
    };

    PictureCallback jpegCallback = new PictureCallback() {
      public void onPictureTaken(byte[] data, Camera _camera) {
          FileOutputStream outStream = null;
            try {
                // write to local sandbox file system
                // outStream =
                // CameraDemo.this.openFileOutput(String.format("%d.jpg",
                // System.currentTimeMillis()), 0);
                // Or write to sdcard
                FrameLayout view = (FrameLayout)findViewById(R.id.image);
                view.setDrawingCacheEnabled(true);
                Bitmap b = view.getDrawingCache();
                b.compress(CompressFormat.PNG, 95, new FileOutputStream(Environment.getExternalStorageDirectory() + String.format(
                        "/SimpleBulb/%d.png", System.currentTimeMillis())));
                /*outStream = new FileOutputStream(Environment.getExternalStorageDirectory() + String.format(
                        "/SimpleBulb/%d.jpeg", System.currentTimeMillis()));
                sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED, Uri.parse("file://"+ Environment.getExternalStorageDirectory())));
                outStream.write(data);
                outStream.close();*/
                Log.d(TAG, "onPictureTaken - wrote bytes: " + data.length);
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
            }
            Log.d(TAG, "onPictureTaken - jpeg");
      }
    };

 // ----------------------------------------------------------------------

    class Preview extends SurfaceView implements SurfaceHolder.Callback {
        SurfaceHolder mHolder;

        Preview(Context context) {
            super(context);

            // Install a SurfaceHolder.Callback so we get notified when the
            // underlying surface is created and destroyed.
            mHolder = getHolder();
            mHolder.addCallback(this);
            mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
        }

        public void surfaceCreated(SurfaceHolder holder) {
            // The Surface has been created, acquire the camera and tell it where
            // to draw.
            mCamera = Camera.open();
            try {
               mCamera.setPreviewDisplay(holder);
               mCamera.setPreviewCallback(new PreviewCallback() {

                public void onPreviewFrame(byte[] data, Camera arg1) {
                    FileOutputStream outStream = null;
                    try {
                        outStream = new FileOutputStream(Environment.getExternalStorageDirectory().toString());
                        outStream.write(data);
                        outStream.close();
                        Log.d(TAG, "onPreviewFrame - wrote bytes: "
                                + data.length);
                    } catch (FileNotFoundException e) {
                        e.printStackTrace();
                    } catch (IOException e) {
                        e.printStackTrace();
                    } finally {
                    }
                    Preview.this.invalidate();
                }
            });
        } catch (IOException e) {
                mCamera.release();
                mCamera = null;
                e.printStackTrace();
            }
        }

        public void surfaceDestroyed(SurfaceHolder holder) {
            // Surface will be destroyed when we return, so stop the preview.
            // Because the CameraDevice object is not a shared resource, it's very
            // important to release it when the activity is paused.
            mCamera.stopPreview();
            mCamera.release();
            mCamera = null;
        }


        private Size getOptimalPreviewSize(List<Size> sizes, int w, int h) {
            final double ASPECT_TOLERANCE = 0.05;
            double targetRatio = (double) w / h;
            if (sizes == null) return null;

            Size optimalSize = null;
            double minDiff = Double.MAX_VALUE;

            int targetHeight = h;

            // Try to find an size match aspect ratio and size
            for (Size size : sizes) {
                double ratio = (double) size.width / size.height;
                if (Math.abs(ratio - targetRatio) > ASPECT_TOLERANCE) continue;
                if (Math.abs(size.height - targetHeight) < minDiff) {
                    optimalSize = size;
                    minDiff = Math.abs(size.height - targetHeight);
                }
            }

            // Cannot find the one match the aspect ratio, ignore the requirement
            if (optimalSize == null) {
                minDiff = Double.MAX_VALUE;
                for (Size size : sizes) {
                    if (Math.abs(size.height - targetHeight) < minDiff) {
                        optimalSize = size;
                        minDiff = Math.abs(size.height - targetHeight);
                    }
                }
            }
            return optimalSize;
        }

        public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
            // Now that the size is known, set up the camera parameters and begin
            // the preview.
            Camera.Parameters parameters = mCamera.getParameters();

            List<Size> sizes = parameters.getSupportedPreviewSizes();
            Size optimalSize = getOptimalPreviewSize(sizes, w, h);

            Display display = ((WindowManager)getSystemService(WINDOW_SERVICE)).getDefaultDisplay();

            if(display.getRotation() == Surface.ROTATION_0)
            {
                parameters.setPreviewSize(optimalSize.height, optimalSize.width);                           
                mCamera.setDisplayOrientation(90);
            }

            if(display.getRotation() == Surface.ROTATION_90)
            {
                parameters.setPreviewSize(optimalSize.width, optimalSize.height);                         
            }

            if(display.getRotation() == Surface.ROTATION_180)
            {
                parameters.setPreviewSize(optimalSize.width, optimalSize.height);               
            }

            if(display.getRotation() == Surface.ROTATION_270)
            {
                parameters.setPreviewSize(optimalSize.width, optimalSize.height);
                mCamera.setDisplayOrientation(0);
            }

            mCamera.setParameters(parameters);
            mCamera.startPreview();
        }

    }

}

在这里是我的布局:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="fill_parent"
    android:layout_height="fill_parent" android:id="@+id/layout">
    <TextView android:layout_width="fill_parent"
        android:layout_height="wrap_content" android:text="SimpleBulb Vision"
        android:textSize="24sp" />

    <FrameLayout android:id="@+id/image" android:layout_weight="1" android:layout_width="fill_parent"
        android:layout_height="fill_parent">

    <FrameLayout android:id="@+id/preview"
        android:layout_weight="1" android:layout_width="fill_parent"
        android:layout_height="fill_parent">
    </FrameLayout>

    <ImageView android:id="@+id/bulb" android:src="@drawable/litbulb"
                   android:layout_width="match_parent"
                   android:layout_height="112dip" />

    </FrameLayout>

    <Button android:layout_width="match_parent"
        android:layout_height="wrap_content" android:id="@+id/buttonClick"
        android:text="Snap!" android:layout_gravity="center" android:onClick="snap"></Button>

</LinearLayout>

推荐答案

我非常乐意说我认为这一点.出于某种原因getDrawingCache()不会抓住捕获的图像.所以我保存了SD卡上的图像,将图像放回视图中,然后使用上述方法保存为一个.这效果良好,尽管由于两次压缩图像而丢失了一些质量.如果有人需要代码,请随时拍我一条消息.

本文地址:https://www.itbaoku.cn/post/102656.html

问题描述

So I was looking at this thread on how to save an overlay on a picture. Android save view to jpg or png

I have my code taking the picture and saving the image just like the answer in that thread suggests. The problem is that it's saving just the overlay with a black background. The actual picture that was taken is not part of the image. Here is my code:

package com.commonsware.android.skeleton;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.Bitmap.CompressFormat;
import android.hardware.Camera;
import android.hardware.Camera.*;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import android.view.Display;
import android.view.Surface;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.widget.FrameLayout;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.List;

// ----------------------------------------------------------------------

public class SimpleBulbActivity extends Activity {
    private Preview mPreview;
    private static final String TAG = "CameraDemo";
    FrameLayout preview;
    Camera mCamera;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        // Hide the window title.
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        // create a File object for the parent directory
        File imageDirectory = new File(Environment.getExternalStorageDirectory() + "/SimpleBulb/");
        // Check if the directory exists
        if(!imageDirectory.exists()) {
            // have the object build the directory structure, if needed.
            imageDirectory.mkdirs();
        }
        setContentView(R.layout.main);
    }

    protected void onResume() {
        super.onResume();
        //Setup the FrameLayout with the Camera Preview Screen
        mPreview = new Preview(this);
        preview = (FrameLayout)findViewById(R.id.preview); 
        preview.addView(mPreview);
    }

    public void snap(View view) {
        mCamera.takePicture(shutterCallback, rawCallback, jpegCallback);
    }
    ShutterCallback shutterCallback = new ShutterCallback() {
      public void onShutter() {
          Log.d(TAG, "onShutter'd");
      }
    };

    PictureCallback rawCallback = new PictureCallback() {
      public void onPictureTaken(byte[] _data, Camera _camera) {
          Log.d(TAG, "onPictureTaken - raw");
      }
    };

    PictureCallback jpegCallback = new PictureCallback() {
      public void onPictureTaken(byte[] data, Camera _camera) {
          FileOutputStream outStream = null;
            try {
                // write to local sandbox file system
                // outStream =
                // CameraDemo.this.openFileOutput(String.format("%d.jpg",
                // System.currentTimeMillis()), 0);
                // Or write to sdcard
                FrameLayout view = (FrameLayout)findViewById(R.id.image);
                view.setDrawingCacheEnabled(true);
                Bitmap b = view.getDrawingCache();
                b.compress(CompressFormat.PNG, 95, new FileOutputStream(Environment.getExternalStorageDirectory() + String.format(
                        "/SimpleBulb/%d.png", System.currentTimeMillis())));
                /*outStream = new FileOutputStream(Environment.getExternalStorageDirectory() + String.format(
                        "/SimpleBulb/%d.jpeg", System.currentTimeMillis()));
                sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED, Uri.parse("file://"+ Environment.getExternalStorageDirectory())));
                outStream.write(data);
                outStream.close();*/
                Log.d(TAG, "onPictureTaken - wrote bytes: " + data.length);
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
            }
            Log.d(TAG, "onPictureTaken - jpeg");
      }
    };

 // ----------------------------------------------------------------------

    class Preview extends SurfaceView implements SurfaceHolder.Callback {
        SurfaceHolder mHolder;

        Preview(Context context) {
            super(context);

            // Install a SurfaceHolder.Callback so we get notified when the
            // underlying surface is created and destroyed.
            mHolder = getHolder();
            mHolder.addCallback(this);
            mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
        }

        public void surfaceCreated(SurfaceHolder holder) {
            // The Surface has been created, acquire the camera and tell it where
            // to draw.
            mCamera = Camera.open();
            try {
               mCamera.setPreviewDisplay(holder);
               mCamera.setPreviewCallback(new PreviewCallback() {

                public void onPreviewFrame(byte[] data, Camera arg1) {
                    FileOutputStream outStream = null;
                    try {
                        outStream = new FileOutputStream(Environment.getExternalStorageDirectory().toString());
                        outStream.write(data);
                        outStream.close();
                        Log.d(TAG, "onPreviewFrame - wrote bytes: "
                                + data.length);
                    } catch (FileNotFoundException e) {
                        e.printStackTrace();
                    } catch (IOException e) {
                        e.printStackTrace();
                    } finally {
                    }
                    Preview.this.invalidate();
                }
            });
        } catch (IOException e) {
                mCamera.release();
                mCamera = null;
                e.printStackTrace();
            }
        }

        public void surfaceDestroyed(SurfaceHolder holder) {
            // Surface will be destroyed when we return, so stop the preview.
            // Because the CameraDevice object is not a shared resource, it's very
            // important to release it when the activity is paused.
            mCamera.stopPreview();
            mCamera.release();
            mCamera = null;
        }


        private Size getOptimalPreviewSize(List<Size> sizes, int w, int h) {
            final double ASPECT_TOLERANCE = 0.05;
            double targetRatio = (double) w / h;
            if (sizes == null) return null;

            Size optimalSize = null;
            double minDiff = Double.MAX_VALUE;

            int targetHeight = h;

            // Try to find an size match aspect ratio and size
            for (Size size : sizes) {
                double ratio = (double) size.width / size.height;
                if (Math.abs(ratio - targetRatio) > ASPECT_TOLERANCE) continue;
                if (Math.abs(size.height - targetHeight) < minDiff) {
                    optimalSize = size;
                    minDiff = Math.abs(size.height - targetHeight);
                }
            }

            // Cannot find the one match the aspect ratio, ignore the requirement
            if (optimalSize == null) {
                minDiff = Double.MAX_VALUE;
                for (Size size : sizes) {
                    if (Math.abs(size.height - targetHeight) < minDiff) {
                        optimalSize = size;
                        minDiff = Math.abs(size.height - targetHeight);
                    }
                }
            }
            return optimalSize;
        }

        public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
            // Now that the size is known, set up the camera parameters and begin
            // the preview.
            Camera.Parameters parameters = mCamera.getParameters();

            List<Size> sizes = parameters.getSupportedPreviewSizes();
            Size optimalSize = getOptimalPreviewSize(sizes, w, h);

            Display display = ((WindowManager)getSystemService(WINDOW_SERVICE)).getDefaultDisplay();

            if(display.getRotation() == Surface.ROTATION_0)
            {
                parameters.setPreviewSize(optimalSize.height, optimalSize.width);                           
                mCamera.setDisplayOrientation(90);
            }

            if(display.getRotation() == Surface.ROTATION_90)
            {
                parameters.setPreviewSize(optimalSize.width, optimalSize.height);                         
            }

            if(display.getRotation() == Surface.ROTATION_180)
            {
                parameters.setPreviewSize(optimalSize.width, optimalSize.height);               
            }

            if(display.getRotation() == Surface.ROTATION_270)
            {
                parameters.setPreviewSize(optimalSize.width, optimalSize.height);
                mCamera.setDisplayOrientation(0);
            }

            mCamera.setParameters(parameters);
            mCamera.startPreview();
        }

    }

}

And here is my layout:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="fill_parent"
    android:layout_height="fill_parent" android:id="@+id/layout">
    <TextView android:layout_width="fill_parent"
        android:layout_height="wrap_content" android:text="SimpleBulb Vision"
        android:textSize="24sp" />

    <FrameLayout android:id="@+id/image" android:layout_weight="1" android:layout_width="fill_parent"
        android:layout_height="fill_parent">

    <FrameLayout android:id="@+id/preview"
        android:layout_weight="1" android:layout_width="fill_parent"
        android:layout_height="fill_parent">
    </FrameLayout>

    <ImageView android:id="@+id/bulb" android:src="@drawable/litbulb"
                   android:layout_width="match_parent"
                   android:layout_height="112dip" />

    </FrameLayout>

    <Button android:layout_width="match_parent"
        android:layout_height="wrap_content" android:id="@+id/buttonClick"
        android:text="Snap!" android:layout_gravity="center" android:onClick="snap"></Button>

</LinearLayout>

推荐答案

I'm extremely happy to say that I figured this out. For some reason getDrawingCache() wouldn't grab the captured image. So I saved the image on the SD Card, placed the image back into the view, and then saved them both as one using the above method. This works well, although some quality is lost due to compressing the image twice. If anyone needs code, feel free to shoot me a message.