关于android:如何在保存之前将任何图像与捕获的Camera图像绑定?

How to bind any image with the captured Camera image before saving it?

本问题已经有最佳答案,请猛点这里访问。

Possible Duplicate:
Android: How to overlay-a-bitmap/draw-over a bitmap?

我已经在 amy 应用程序中实现了安卓相机功能。

现在我想将任何透明图像与捕获的相机图像结合起来,然后将该图像保存到图库中,那么如何完成??

任何代码都会被真正欣赏。
谢谢。

编辑:
我正在使用此代码来捕获和保存图像所以,我应该如何实现这些东西。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
takePhotoBtn.setOnClickListener(new OnClickListener() {
        public void onClick(View v) { // <5>

            ImageCaptureCallback iccb = null;

            try {
                String filename = timeStampFormat.format(new Date());
                ContentValues values = new ContentValues();
                values.put(Media.TITLE, filename);
                values.put(Media.DESCRIPTION,"Image capture by camera");
                Uri uri = getContentResolver().insert(Media.EXTERNAL_CONTENT_URI, values);

                iccb = new ImageCaptureCallback( getContentResolver().openOutputStream(uri));

                // to put the Image on captured image.
                Canvas canvas = new Canvas();
                Bitmap kangoo = BitmapFactory.decodeResource(getResources(),
                        R.drawable.icon);
                canvas.drawColor(Color.argb(160, 21, 140, 21));
                canvas.drawBitmap(kangoo, 130, 10, null);


            } catch(Exception ex ){
                ex.printStackTrace();
                Log.e(getClass().getSimpleName(), ex.getMessage(), ex);
            }
          camera.takePicture(mShutterCallback, mPictureCallbackRaw, iccb);
        }
      });


Camera.PictureCallback mPictureCallbackRaw = new Camera.PictureCallback() {
    public void onPictureTaken(byte[] data, Camera c) {
        Log.e(getClass().getSimpleName(),"PICTURE CALLBACK RAW:" + data);
            System.out.println("\
\
\
\
The Data in mPictureCallbackRaw is :"+data);
        //camera.startPreview(); // Added StastPreview();
    }
};

Camera.PictureCallback mPictureCallbackJpeg= new Camera.PictureCallback() {
    public void onPictureTaken(byte[] data, Camera c) {
        Log.e(getClass().getSimpleName(),"PICTURE CALLBACK JPEG: data.length =" + data);
        System.out.println("\
\
\
\
The Data in mPictureCallbackJPEG is :"+data);
        camera.startPreview();
    }
};

Camera.ShutterCallback mShutterCallback = new Camera.ShutterCallback() {
    public void onShutter() {
        Log.e(getClass().getSimpleName(),"SHUTTER CALLBACK");
    }
};




public class ImageCaptureCallback implements PictureCallback  {

private OutputStream filoutputStream;
public ImageCaptureCallback(OutputStream filoutputStream) {
    this.filoutputStream = filoutputStream;
}
@Override
public void onPictureTaken(byte[] data, Camera camera) {
    try {
        Log.v(getClass().getSimpleName(),"onPictureTaken=" + data +" length =" + data.length);

        filoutputStream.write(data);
        filoutputStream.flush();
        filoutputStream.close();


    } catch(Exception ex) {
        ex.printStackTrace();
    }
}

}


尝试将相机图像和透明图像这两个位图结合起来。这是图像的组合并存储在 SDCard 中。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
public Bitmap combineImages(Bitmap c, Bitmap s) {

        Bitmap cs = null;
        int width, height = 0;

        if (c.getWidth() > s.getWidth()) {
            width = c.getWidth();
            height = c.getHeight();
        } else {
            width = s.getWidth() + s.getWidth();
            height = c.getHeight();
        }

        cs = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);

        Canvas comboImage = new Canvas(cs);

        comboImage.drawBitmap(c, 0, 0, null);
        comboImage.drawBitmap(s, 100, 300, null);

        /******
         *
         *   Write file to SDCard
         *
         * ****/

        String tmpImg = String.valueOf(System.currentTimeMillis()) +".png";
        OutputStream os = null;
        try {
            os = new FileOutputStream(Environment.getExternalStorageDirectory()
                    +"/"+tmpImg);
            cs.compress(CompressFormat.PNG, 100, os);
        } catch (IOException e) {
            Log.e("combineImages","problem combining images", e);
        }
        return cs;
    }

Android 实现了多种图像合成算法。这是使用它们的简单方法。我在这台计算机上没有 Eclipse,因此以下代码未经测试(但应该可以工作或至少接近工作)。

img1 和 img2 都是位图,其中一个是您从相机中捕获的。

1) 创建一个新的空位图。我假设 img1 和 img2 的大小相同。如果没有,您可以调整它们的大小或使这个新位图具有最大的大小或其他东西。

1
2
Bitmap compositeImage = Bitmap.createBitmap(img1.getWidth(),
  img1.getWidth(), img1.getContig());

2) 在位图上创建画布

1
Canvas canvas = new Canvas(compositeImage);

3) 在新位图上绘制第一幅图像

1
2
Paint paint = new Paint();
canvas.drawBitmap(img1, 0.0f, 0.0f, paint);

4) Android 在 SDK 中有一套合成算法。这些方法以 Porter 和 Duff 命名,他们撰写了一篇描述合成图像算法的论文。 Android 将此设置称为"传输模式"。要查看可用的 Porter-Duff 传输模式,请访问 http://developer.android.com/reference/android/graphics/PorterDuff.Mode.html 或谷歌搜索。根据您的需要,我建议您查看乘法、变暗和变亮。

1
paint.setXfermode(new PorterDuffXfermode(android.graphics.PorterDuff.Mode.MULTIPLY));

5) 既然已经设置了传输模式,只需绘制第二张图像即可获得你想要的效果

1
canvas.drawBitmap(img2, 0.0f, 0.0f, paint);

现在,compositeImage 位图包含组合图像。

编辑。好的,这是放在一起的代码,也许你可以把它放在你的 PictureCallback 中(jpeg 的,而不是原始的)。同样,它未经测试,但应该是好的或接近好的:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public void onPictureTaken(byte[] data, Camera camera) {
  Bitmap img1 = BitmapFactory.decodeResource(getResources(),
    R.drawable.icon); // assuming you really want to use the icon
  Bitmap img2 = BitmapFactory.decodeByteArray(data, 0, data.length);
  Bitmap composite = Bitmap.createBitmap(img2.getWidth(), img2.getHeight(),
    img2.getConfig());
  Canvas canvas = new Canvas(composite);
  Paint paint = new Paint();
  canvas.drawBitmap(img2, 0.0f, 0.0f, paint);
  paint.setXfermode(new PorterDuffXfermode(android.graphics.PorterDuff.Mode.MULTIPLY));
  canvas.drawBitmap(img1, 0.0f, 0.0f, paint);

  // It seems you want to insert the new image into the gallery
  ContentValues values = ...
  try {
    Uri imageFileUri = getContentResolver().insert(Media.EXTERNAL_CONTENT_URI, values);
    composite.compress(Bitmap.CompressFormat.JPEG, 90,
      getContentResolver().openOutputStream(imageFileUri));
  } catch(Exception) {
    ...
  }
}