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) { ... } } |