ARVR技术交流群:129340649

欢迎增加。

AR场景往往给别人留下的印象深刻,假设模型做的炫丽一点,效果将会更好。

那么怎样保存这一美好的情景呢?这篇文章将教你怎样实现AR场景的拍摄以及永久保存。


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



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


虚实融合场景图层都是这样的架构,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、增强现实场景图像的保存


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

展示几幅我做出来的效果:

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvZ2d0YWFz/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="">


Android AR场景拍照技术实现(有关键源代码)的更多相关文章

  1. Android无埋点数据收集SDK关键技术

    前言 鉴于日益强烈的精细化运营需求,网易乐得从去年开始构建大数据平台,<<无埋点数据收集SDK>>因此立项,用于向大数据平台提供全量,完整,准确的客户端数据. << ...

  2. Android中直播视频技术探究之---基础知识大纲介绍

    一.前言 最近各种视频直播app到处都是,各种霸屏,当然我们也是需要体验的,关于视频直播的软件这里就不介绍了,在不是技术的人来看,直播是一种潮流,是一种娱乐方式,但是作为一个高技术的,我们除了看看,更 ...

  3. 微信团队分享:Kotlin渐被认可,Android版微信的技术尝鲜之旅

    本文由微信开发团队工程是由“oneliang”原创发表于WeMobileDev公众号,内容稍有改动. 1.引言   Kotlin 是一个用于现代多平台应用的静态编程语言,由 JetBrains 开发( ...

  4. Android AR平台

    ARToolkit:https://baike.baidu.com/item/ARToolkit/5726883?fr=aladdin Vuforia:搭建Android AR技术开发环境(Aqume ...

  5. [yueqian_scut]Android多点触控技术和应用框架

    Android多点触控技术跟Linux输入子系统紧密相关.本文将从应用的角度说明Android多点触控技术的接口和应用. 一.多点触控场景分析 网络上有关Android多点触控技术的文章多见于两点拉伸 ...

  6. Android开发60条技术经验总结

    Android开发60条技术经验总结,以下是全文: 1. 全部Activity可继承自BaseActivity,便于统一风格与处理公共事件,构建对话框统一构建器的建立,万一需要整体变动,一处修改到处有 ...

  7. Android实现XML解析技术

    转载:Android实现XML解析技术 本文介绍在Android平台中实现对XML的三种解析方式. XML在各种开发中都广泛应用,Android也不例外.作为承载数据的一个重要角色,如何读写XML成为 ...

  8. Android实现数据存储技术

    转载:Android实现数据存储技术 本文介绍Android中的5种数据存储方式. 数据存储在开发中是使用最频繁的,在这里主要介绍Android平台中实现数据存储的5种方式,分别是: 1 使用Shar ...

  9. Android中Java反射技术的使用示例

    import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.Metho ...

随机推荐

  1. LeetCode728. 自除数

    自除数 是指可以被它包含的每一位数除尽的数. 例如,128 是一个自除数,因为 128 % 1 == 0,128 % 2 == 0,128 % 8 == 0. 还有,自除数不允许包含 0 . 给定上边 ...

  2. css选择器(2)——属性选择器和基于元素结构关系的选择器

    在有些标记语言中,不能使用类名和id选择器,于是css2引入了属性选择器. 3.属性选择器 a)根据是否存在该属性来选择 如果希望选择有某个属性的元素,例如要选择有class属性的所有h1元素,使其文 ...

  3. 【HIHOCODER 1037】 数字三角形

    链接 问题描述 小Hi和小Ho在经历了螃蟹先生的任务之后被奖励了一次出国旅游的机会,于是他们来到了大洋彼岸的美国.美国人民的生活非常有意思,经常会有形形色色.奇奇怪怪的活动举办,这不,小Hi和小Ho刚 ...

  4. pycharm配置git--图文教程

    1.     下载git客户端 2.     File->Default Setting-> Version Control->Git 3.     Path to Git exec ...

  5. 对于2-sat问题的求解

    一.O(n+m) 暴力不多说 二.O(m) 1.构图 2.求图的极大强连通子图 3.把每个子图收缩成单个节点,根据原图关系构造一个有向无环图 4.判断是否有解,无解则输出(退出) 5.对新图进行拓扑排 ...

  6. 【贪心+二分】codeforces C. Sagheer and Nubian Market

    http://codeforces.com/contest/812/problem/C [题意] 如何花最少的钱买最多的纪念品?首要满足纪念品尽可能多,纪念品数量一样花钱要最少,输出纪念品数量以及最少 ...

  7. 获得HttpServletRequest 和HttpSession对象

    package org.jeecgframework.core.util; import java.util.HashMap; import java.util.Map; import javax.s ...

  8. 从零开始写STL-二叉搜索树

    二叉查找树(Binary Search Tree),(又:二叉搜索树,二叉排序树)它或者是一棵空树,或者是具有下列性质的二叉树: 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值: 若它的 ...

  9. MySQL基础架构

    前段时间订阅了<Mysql实战45讲>(从原理到实战),新的一年为自己充充电.对于这部分内容,我所知道的只来源于我大学里学习的课程<数据库原理>,在大学里学习的只是简单的查询, ...

  10. [Bzoj2120]数颜色 (非正解 )(莫队)

    2120: 数颜色 Time Limit: 6 Sec  Memory Limit: 259 MBSubmit: 6286  Solved: 2489[Submit][Status][Discuss] ...