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

查看:85
本文介绍了保存叠印图像的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

所以我如何保存覆盖在图片上看着这个线程。 Android的保存以JPG或PNG

我有我的code拍摄照片并保存,就像在该线程的回答暗示的图像。现在的问题是,它的节能只是一个黑色背景覆盖。已采取的实际画面不是图像的一部分。这是我的code:

 包com.commonsware.android.skeleton;

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

进口的java.io.File;
进口java.io.FileNotFoundException;
进口java.io.FileOutputStream中;
进口java.io.IOException异常;
进口的java.util.List;

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

公共类SimpleBulbActivity延伸活动{
    私人preVIEW米preVIEW;
    私有静态最后字符串变量=CameraDemo;
    的FrameLayout preVIEW;
    相机mCamera;

    @覆盖
    保护无效的onCreate(包savedInstanceState){
        super.onCreate(savedInstanceState);

        //隐藏窗口标题。
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        //创建父目录的File对象
        文件imageDirectory =新的文件(Environment.getExternalStorageDirectory()+/ SimpleBulb /);
        //检查目录存在
        如果(!imageDirectory.exists()){
            //具有对象建立的目录结构,如果需要的话。
            imageDirectory.mkdirs();
        }
        的setContentView(R.layout.main);
    }

    保护无效onResume(){
        super.onResume();
        //设置与相机preVIEW屏幕中的FrameLayout
        米preVIEW =新的preVIEW(本);
        preVIEW =(的FrameLayout)findViewById(R.id. preVIEW);
        preview.addView(M preVIEW);
    }

    公共无效卡(查看视图){
        mCamera.takePicture(shutterCallback,rawCallback,jpegCallback);
    }
    ShutterCallback shutterCallback =新ShutterCallback(){
      公共无效onShutter(){
          Log.d(TAG,onShutter'd);
      }
    };

    PictureCallback rawCallback =新PictureCallback(){
      公共无效onPictureTaken(byte []的_data,摄像机_camera){
          Log.d(TAG,onPictureTaken  - 生);
      }
    };

    PictureCallback jpegCallback =新PictureCallback(){
      公共无效onPictureTaken(byte []的数据,摄像机_camera){
          FileOutputStream中outStream = NULL;
            尝试 {
                //写入本地沙箱文件系统
                // outStream =
                // CameraDemo.this.openFileOutput(的String.Format(%D.JPG
                // System.currentTimeMillis的()),0);
                //或写入SD卡
                的FrameLayout视图=(的FrameLayout)findViewById(R.id.image);
                view.setDrawingCacheEnabled(真正的);
                位图B = view.getDrawingCache();
                b.com preSS(比较pressFormat.PNG,95,新的FileOutputStream(Environment.getExternalStorageDirectory()+的String.Format(
                        /SimpleBulb/%d.png,System.currentTimeMillis的())));
                / * outStream =新的FileOutputStream(Environment.getExternalStorageDirectory()+的String.Format(
                        /SimpleBulb/%d.jpeg,System.currentTimeMillis的()));
                sendBroadcast(新意图(Intent.ACTION_MEDIA_MOUNTED,Uri.parse(文件://+ Environment.getExternalStorageDirectory())));
                outStream.write(数据);
                outStream.close(); * /
                Log.d(TAG,onPictureTaken  - 写字节:+ data.length);
            }赶上(FileNotFoundException异常E){
                e.printStackTrace();
            }赶上(IOException异常E){
                e.printStackTrace();
            } 最后 {
            }
            Log.d(TAG,onPictureTaken  -  JPEG);
      }
    };

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

    类preVIEW延伸SurfaceView实现SurfaceHolder.Callback {
        SurfaceHolder mHolder;

        preVIEW(上下文的背景下){
            超(上下文);

            //安装SurfaceHolder.Callback所以我们得到通知时,该
            //下垫面创建和销毁。
            mHolder = getHolder();
            mHolder.addCallback(本);
            mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
        }

        公共无效surfaceCreated(SurfaceHolder持有者){
            //表面经创建,获取摄像机,并告诉它在哪里
            //绘制。
            mCamera = Camera.open();
            尝试 {
               mCamera.set previewDisplay(保持器);
               mCamera.set previewCallback(新previewCallback(){

                在previewFrame(byte []的数据,摄像机ARG1){公共无效
                    FileOutputStream中outStream = NULL;
                    尝试 {
                        outStream =新的FileOutputStream(Environment.getExternalStorageDirectory()的toString());
                        outStream.write(数据);
                        outStream.close();
                        Log.d(TAG,在previewFrame  - 写字节
                                + data.length);
                    }赶上(FileNotFoundException异常E){
                        e.printStackTrace();
                    }赶上(IOException异常E){
                        e.printStackTrace();
                    } 最后 {
                    }
                    preview.this.invalidate();
                }
            });
        }赶上(IOException异常E){
                mCamera.release();
                mCamera = NULL;
                e.printStackTrace();
            }
        }

        公共无效surfaceDestroyed(SurfaceHolder持有者){
            //面,当我们返回将被销毁,所以停止了preVIEW。
            //因为CameraDevice对象不是共享资源,这是非常
            //重要的是要释放它当活动被暂停。
            mCamera.stop preVIEW();
            mCamera.release();
            mCamera = NULL;
        }


        私人大小getOptimal previewSize(名单<大小>的大小,INT W,INT高){
            最终双ASPECT_TOLERANCE = 0.05;
            双targetRatio =(双)W / H;
            如果(大小== NULL)返回NULL;

            大小optimalSize = NULL;
            双minDiff = Double.MAX_VALUE;

            INT targetHeight = H;

            //试着找一个大小匹配纵横比和尺寸
            对于(尺寸大小:大小){
                双率=(双)size.width / size.height;
                如果(Math.abs(比 -  targetRatio)> ASPECT_TOLERANCE)继续;
                如果(Math.abs(size.height  -  targetHeight)< minDiff){
                    optimalSize =大小;
                    minDiff = Math.abs(size.height  -  targetHeight);
                }
            }

            //不能找到一个匹配的纵横比,忽略此要求
            如果(optimalSize == NULL){
                minDiff = Double.MAX_VALUE;
                对于(尺寸大小:大小){
                    如果(Math.abs(size.height  -  targetHeight)< minDiff){
                        optimalSize =大小;
                        minDiff = Math.abs(size.height  -  targetHeight);
                    }
                }
            }
            返回optimalSize;
        }

        公共无效surfaceChanged(SurfaceHolder持有人,INT格式,INT W,INT高){
            //现在的尺寸是已知的,设置相机参数,并开始
            //在preVIEW。
            Camera.Parameters参数= mCamera.getParameters();

            名单<大小>大小= parameters.getSupported previewSizes();
            大小optimalSize = getOptimal previewSize(尺寸,W,H);

            显示显示=((窗口管理器)getSystemService(WINDOW_SERVICE))getDefaultDisplay()。

            如果(display.getRotation()== Surface.ROTATION_0)
            {
                parameters.set previewSize(optimalSize.height,optimalSize.width);
                mCamera.setDisplayOrientation(90);
            }

            如果(display.getRotation()== Surface.ROTATION_90)
            {
                parameters.set previewSize(optimalSize.width,optimalSize.height);
            }

            如果(display.getRotation()== Surface.ROTATION_180)
            {
                parameters.set previewSize(optimalSize.width,optimalSize.height);
            }

            如果(display.getRotation()== Surface.ROTATION_270)
            {
                parameters.set previewSize(optimalSize.width,optimalSize.height);
                mCamera.setDisplayOrientation(0);
            }

            mCamera.setParameters(参数);
            mCamera.start preVIEW();
        }

    }

}
 

这里是我的布局:

 < XML版本=1.0编码=UTF-8&GT?;
< LinearLayout中的xmlns:机器人=htt​​p://schemas.android.com/apk/res/android
    机器人:方向=垂直机器人:layout_width =FILL_PARENT
    机器人:layout_height =FILL_PARENT机器人:ID =@ + ID /布局>
    < TextView的Andr​​oid的:layout_width =FILL_PARENT
        机器人:layout_height =WRAP_CONTENT机器人:文本=SimpleBulb愿景
        机器人:TEXTSIZE =24sp/>

    <的FrameLayout机器人:ID =@ + ID /图片机器人:layout_weight =1机器人:layout_width =FILL_PARENT
        机器人:layout_height =FILL_PARENT>

    <的FrameLayout机器人:ID =@ + ID / preVIEW
        机器人:layout_weight =1机器人:layout_width =FILL_PARENT
        机器人:layout_height =FILL_PARENT>
    < /的FrameLayout>

    < ImageView的机器人:ID =@ + ID /灯泡机器人:SRC =@可绘制/ litbulb
                   机器人:layout_width =match_parent
                   机器人:layout_height =112dip/>

    < /的FrameLayout>

    <按钮机器人:layout_width =match_parent
        机器人:layout_height =WRAP_CONTENT机器人:ID =@ + ID / buttonClick
        机器人:文本=快!机器人:layout_gravity =中心安卓的onClick =啪>< /按钮>

< / LinearLayout中>
 

解决方案

我非常高兴地说,我想通了这一点。出于某种原因, getDrawingCache()不会抢拍摄的图像。所以,我救在图像上的SD卡,放置在图像放回视图,然后用上述方法保存他们两个为一体。这种运作良好,但也有一些质量损失,由于COM pressing图像的两倍。如果有人需要code,随意拍我一个消息。

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.

这篇关于保存叠印图像的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆