码迷,mamicode.com
首页 > 其他好文 > 详细

拍摄AR场景技术实现(有关键源码)

时间:2014-05-06 21:32:35      阅读:605      评论:0      收藏:0      [点我收藏+]

标签:opengl   ar   技术   源码   

AR场景往往给别人留下的印象深刻,如果模型做的炫丽一点,效果将会更好。那么如何保存这一美好的情景呢?这篇文章将教你如何实现AR场景的拍摄以及永久保存。


1、AR虚实融合场景图层的分析


bubuko.com,布布扣
bubuko.com,布布扣

一个简单的AR场景,在任何系统下的布局方式都不外乎上图所示的类型。本文以在Android系统下的增强现实为例。

bubuko.com,布布扣
bubuko.com,布布扣

虚实融合场景图层都是这种架构,GLSurfaceView用于绘制三维虚拟模型,SurfaceView是显示真实场景视频帧画面,如果使用OpenCV进行图像获取的话,就使用SurfaceView的子类CameraBridgeViewBase。这些布局类的作用应该分的比较清楚。


2、场景获取思路


首先由于真实场景的视频帧画面和三维虚拟模型不在同一个图层上,我们需要分别获取不同图层上的图像,再将它们转换成位图,最后拼合成一张位图图片就可以了。但是传统的拍照方式只能获取真实的场景,无法获取OpenGL渲染的画面。这里就是用传统的方式获取视频图像即可,主要要解决GLSurfaceView上的三维模型。怎么样将三维虚拟模型转化成一张图片?


3、视频帧图像的获取


在Android系统中,

①使用Camera的情况:
参见这里的方法:Android拍照的两种方式http://blog.csdn.net/napolun007/article/details/6103307
或者参见官网:http://developer.android.com/training/camera/photobasics.html
②使用OpenCV的情况:
     使用OpenCV中的Utils.matToBitmap(Mat mat, Bitmap bmp),将获取的视频帧转换成Bitmap就可以了。


4、OpenGL渲染模型转化成位图


     主要是将OpenGL绘制的图像转化成像素数据。了解下glReadPixels参数的含义:
     void glReadPixels( GLint x, GLint y, GLsizei width,GLsizei height, GLenum format, GLenum type, GLvoid *pixels) ;
     前面几个参数指定读取的位置尺寸以及格式, 最后一个参数用来返回结果, 所以像素数据自然是读到pixels中。最后的方法代码如下图所示:

// 保存GL绘制的图形
public static Bitmap saveGLBitmap(int width_surface, int height_surface)
{
// isSave = false;
int w = width_surface;
int h = height_surface;

Log.i("hari", "w:" + w + "-----h:" + h);

int b[] = new int[(int) (w * h)];
int bt[] = new int[(int) (w * h)];
IntBuffer buffer = IntBuffer.wrap(b);
buffer.position(0);
GLES20.glReadPixels(0, 0, w, h, GLES20.GL_RGBA,
GLES20.GL_UNSIGNED_BYTE, buffer);
for (int i = 0; i < h; i++) {
/**
* 由于OpenGL与Android的Bitmap不兼容,这里需要进行一些校正
*/
for (int j = 0; j < w; j++) {
int pix = b[i * w + j];
int pb = (pix >> 16) & 0xff;
int pr = (pix << 16) & 0x00ff0000;
int pix1 = (pix & 0xff00ff00) | pr | pb;
bt[(h - i - 1) * w + j] = pix1;
}
}
Bitmap inBitmap = null;
if (inBitmap == null || !inBitmap.isMutable()
|| inBitmap.getWidth() != w
|| inBitmap.getHeight() != h) {
inBitmap = Bitmap.createBitmap(w, h,
Bitmap.Config.ARGB_8888);
}
// Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
inBitmap.copyPixelsFromBuffer(buffer);
// return inBitmap ;
// return Bitmap.createBitmap(bt, w, h,
// Bitmap.Config.ARGB_8888);
inBitmap = Bitmap.createBitmap(bt, w, h,
Bitmap.Config.ARGB_8888);

ByteArrayOutputStream bos = new ByteArrayOutputStream();
inBitmap.compress(CompressFormat.PNG, 90, bos);
byte[] bitmapdata = bos.toByteArray();
ByteArrayInputStream fis = new ByteArrayInputStream(bitmapdata);

// final Calendar c=Calendar.getInstance();
// long mytimestamp=c.getTimeInMillis();
// String timeStamp=String.valueOf(mytimestamp);
// String myfile="hari"+timeStamp+".jpeg";

File dir_image = new File(Environment.getExternalStorageDirectory()
+ File.separator + "printerscreenshots");
dir_image.mkdirs();

try {
File tmpFile = new File(dir_image + "/"
+ System.currentTimeMillis() + ".png");
FileOutputStream fos = new FileOutputStream(tmpFile);

byte[] buf = new byte[1024];
int len;
while ((len = fis.read(buf)) > 0) {
fos.write(buf, 0, len);
}
fis.close();
fos.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return inBitmap;
}


5、图像的拼合


这个比较简单,就是将两个位图拼合成一幅位图,可以使用Canvas绘图板进行绘制。

public static Bitmap combineBitmap(Bitmap background, Bitmap foreground) {

if (background == null) {
return null;
}

int bgWidth = background.getWidth();

int bgHeight = background.getHeight();

int fgWidth = foreground.getWidth();

int fgHeight = foreground.getHeight();

Bitmap newmap = Bitmap

.createBitmap(bgWidth, bgHeight, Config.ARGB_8888);

Canvas canvas = new Canvas(newmap);

canvas.drawBitmap(background, 0, 0, null);

canvas.drawBitmap(foreground, (bgWidth - fgWidth) / 2,

(bgHeight - fgHeight) / 2, null);

canvas.save(Canvas.ALL_SAVE_FLAG);

canvas.restore();

return newmap;

}


6、增强现实场景图像的保存


这个使用传统的文件保存方法即可。

展示几幅我做出来的效果:
bubuko.com,布布扣bubuko.com,布布扣bubuko.com,布布扣bubuko.com,布布扣

拍摄AR场景技术实现(有关键源码),布布扣,bubuko.com

拍摄AR场景技术实现(有关键源码)

标签:opengl   ar   技术   源码   

原文地址:http://blog.csdn.net/ggtaas/article/details/25104665

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!