相机叠加图片黑色

发布于 2024-12-22 19:51:17 字数 11569 浏览 0 评论 0原文

编辑:正如 Oren Bengigi 建议的那样,我尝试将保存数据的代码位封装在 post 中(可运行),但我仍然得到相同的结果:

final Handler handler = new Handler();
    void savePicture(final byte[] data) {
        handler.post(new Runnable() {
            public void run() {
                try {
                    FrameLayout view = (FrameLayout)findViewById(R.id.image);
                    view.setDrawingCacheEnabled(true);
                    Bitmap b = view.getDrawingCache();
                    b.compress(CompressFormat.PNG, 50, new FileOutputStream(Environment.getExternalStorageDirectory() + String.format(
                            "/SimpleBulb/%d.png", System.currentTimeMillis())));
                    Log.d(TAG, "onPictureTaken - wrote bytes: " + data.length);
                } catch (FileNotFoundException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                } finally {
                }
            }
        });
    }

我尝试拍摄一张带有叠加层的照片并将两者保存为一个 .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.graphics.BitmapFactory;
import android.hardware.Camera;
import android.hardware.Camera.*;
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 android.widget.ImageView;
import android.widget.RelativeLayout;

import java.io.BufferedOutputStream;
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";
    RelativeLayout 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 = (RelativeLayout)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);
                // Save image to SD Card
                /*BitmapFactory.Options options=new BitmapFactory.Options();
                options.inSampleSize = 5;
                String filename = Environment.getExternalStorageDirectory() + String.format(
                        "/SimpleBulb/%d.png", System.currentTimeMillis());
                Bitmap myImage = BitmapFactory.decodeByteArray(data, 0,data.length,options);
                outStream = new FileOutputStream(filename);
                BufferedOutputStream bos = new BufferedOutputStream(outStream);
                myImage.compress(CompressFormat.PNG, 95, bos);
                bos.flush();
                bos.close();            

                // Replace view with Picture taken
                ImageView cameraImage = (ImageView)findViewById(R.id.taken_image);
                cameraImage.setImageBitmap(myImage);*/

                // Save as one
                FrameLayout view = (FrameLayout)findViewById(R.id.image);
                view.setDrawingCacheEnabled(true);
                Bitmap b = view.getDrawingCache();
                b.compress(CompressFormat.PNG, 50, new FileOutputStream(Environment.getExternalStorageDirectory() + String.format(
                        "/SimpleBulb/%d.png", System.currentTimeMillis())));
                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) {
                        Log.d(TAG, "onPreviewFrame - wrote bytes: "
                                + data.length);

                    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">

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

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

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

    </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>

EDIT: As Oren Bengigi suggested, I tried enclosing the bit of code that saves the data in a post(Runnable), but I'm still getting the same results:

final Handler handler = new Handler();
    void savePicture(final byte[] data) {
        handler.post(new Runnable() {
            public void run() {
                try {
                    FrameLayout view = (FrameLayout)findViewById(R.id.image);
                    view.setDrawingCacheEnabled(true);
                    Bitmap b = view.getDrawingCache();
                    b.compress(CompressFormat.PNG, 50, new FileOutputStream(Environment.getExternalStorageDirectory() + String.format(
                            "/SimpleBulb/%d.png", System.currentTimeMillis())));
                    Log.d(TAG, "onPictureTaken - wrote bytes: " + data.length);
                } catch (FileNotFoundException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                } finally {
                }
            }
        });
    }

I am trying to take a picture with an overlay and save both as one .png. I am able to save the image the camera captures, and I'm able to save the overlay, but when I try to save both as one image, I only see the overlay and a black background. I've switched the two layers and the entire image was black, so the picture from the camera is just being rendered black. Any help on this would be GREATLY appreciated. Here's 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.graphics.BitmapFactory;
import android.hardware.Camera;
import android.hardware.Camera.*;
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 android.widget.ImageView;
import android.widget.RelativeLayout;

import java.io.BufferedOutputStream;
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";
    RelativeLayout 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 = (RelativeLayout)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);
                // Save image to SD Card
                /*BitmapFactory.Options options=new BitmapFactory.Options();
                options.inSampleSize = 5;
                String filename = Environment.getExternalStorageDirectory() + String.format(
                        "/SimpleBulb/%d.png", System.currentTimeMillis());
                Bitmap myImage = BitmapFactory.decodeByteArray(data, 0,data.length,options);
                outStream = new FileOutputStream(filename);
                BufferedOutputStream bos = new BufferedOutputStream(outStream);
                myImage.compress(CompressFormat.PNG, 95, bos);
                bos.flush();
                bos.close();            

                // Replace view with Picture taken
                ImageView cameraImage = (ImageView)findViewById(R.id.taken_image);
                cameraImage.setImageBitmap(myImage);*/

                // Save as one
                FrameLayout view = (FrameLayout)findViewById(R.id.image);
                view.setDrawingCacheEnabled(true);
                Bitmap b = view.getDrawingCache();
                b.compress(CompressFormat.PNG, 50, new FileOutputStream(Environment.getExternalStorageDirectory() + String.format(
                        "/SimpleBulb/%d.png", System.currentTimeMillis())));
                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) {
                        Log.d(TAG, "onPreviewFrame - wrote bytes: "
                                + data.length);

                    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();
        }

    }

}

Here's 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">

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

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

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

    </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>

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

苍风燃霜 2024-12-29 19:51:17

您设置的 ImageView 可能不会立即更新。
我会尝试运行以下代码:

  Bitmap b = view.getDrawingCache();
            b.compress(CompressFormat.PNG, 50, new FileOutputStream(Environment.getExternalStorageDirectory() + String.format(
                    "/SimpleBulb/%d.png", System.currentTimeMillis())));
            Log.d(TAG, "onPictureTaken - wrote bytes: " + data.length);

在带有 postRunaable 的处理程序中,看看它是否有效。

It might be that the ImageView that you set, doesn't update immediately.
What I would try is running the follwoing code:

  Bitmap b = view.getDrawingCache();
            b.compress(CompressFormat.PNG, 50, new FileOutputStream(Environment.getExternalStorageDirectory() + String.format(
                    "/SimpleBulb/%d.png", System.currentTimeMillis())));
            Log.d(TAG, "onPictureTaken - wrote bytes: " + data.length);

in a handler with postRunaable and see if it works.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文