Android AR场景拍照技术实现(有关键源代码)
ARVR技术交流群:129340649
欢迎增加。
AR场景往往给别人留下的印象深刻,假设模型做的炫丽一点,效果将会更好。
那么怎样保存这一美好的情景呢?这篇文章将教你怎样实现AR场景的拍摄以及永久保存。
1、AR虚实融合场景图层的分析

一个简单的AR场景,在不论什么系统下的布局方式都不外乎上图所看到的的类型。本文以在Android系统下的增强现实为例。
.png)
虚实融合场景图层都是这样的架构,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场景拍照技术实现(有关键源代码)的更多相关文章
- Android无埋点数据收集SDK关键技术
前言 鉴于日益强烈的精细化运营需求,网易乐得从去年开始构建大数据平台,<<无埋点数据收集SDK>>因此立项,用于向大数据平台提供全量,完整,准确的客户端数据. << ...
- Android中直播视频技术探究之---基础知识大纲介绍
一.前言 最近各种视频直播app到处都是,各种霸屏,当然我们也是需要体验的,关于视频直播的软件这里就不介绍了,在不是技术的人来看,直播是一种潮流,是一种娱乐方式,但是作为一个高技术的,我们除了看看,更 ...
- 微信团队分享:Kotlin渐被认可,Android版微信的技术尝鲜之旅
本文由微信开发团队工程是由“oneliang”原创发表于WeMobileDev公众号,内容稍有改动. 1.引言 Kotlin 是一个用于现代多平台应用的静态编程语言,由 JetBrains 开发( ...
- Android AR平台
ARToolkit:https://baike.baidu.com/item/ARToolkit/5726883?fr=aladdin Vuforia:搭建Android AR技术开发环境(Aqume ...
- [yueqian_scut]Android多点触控技术和应用框架
Android多点触控技术跟Linux输入子系统紧密相关.本文将从应用的角度说明Android多点触控技术的接口和应用. 一.多点触控场景分析 网络上有关Android多点触控技术的文章多见于两点拉伸 ...
- Android开发60条技术经验总结
Android开发60条技术经验总结,以下是全文: 1. 全部Activity可继承自BaseActivity,便于统一风格与处理公共事件,构建对话框统一构建器的建立,万一需要整体变动,一处修改到处有 ...
- Android实现XML解析技术
转载:Android实现XML解析技术 本文介绍在Android平台中实现对XML的三种解析方式. XML在各种开发中都广泛应用,Android也不例外.作为承载数据的一个重要角色,如何读写XML成为 ...
- Android实现数据存储技术
转载:Android实现数据存储技术 本文介绍Android中的5种数据存储方式. 数据存储在开发中是使用最频繁的,在这里主要介绍Android平台中实现数据存储的5种方式,分别是: 1 使用Shar ...
- Android中Java反射技术的使用示例
import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.Metho ...
随机推荐
- iframe的操作switch_to_frame使用方法.
一.frame和iframe区别 Frame与Iframe两者可以实现的功能基本相同,不过Iframe比Frame具有更多的灵活性. frame是整个页面的框架,iframe是内嵌的网页元素,也可以说 ...
- solr中的Tokenizer Filter
Tokenizer Tokenizer 的工作是将文本流分解为令牌,其中每个令牌(通常)是文本中字符的子序列.分析器知道它配置的字段,但 tokenizer 不是.Tokenizers 从字符流(Re ...
- UVa 12118 检查员的难题 (dfs判连通, 构造欧拉通路)
题意: 分析: 欧拉通路:图连通:图中只有0个或2个度为奇数的结点 这题我们只需要判断选择的边构成多少个联通块, 再记录全部联通块一共有多少个奇度顶点. 然后我们在联通块中连线, 每次连接两个联通块就 ...
- Java学习之集合框架的迭代器--Iteratorjk及ListItertor接口
通常情况下,你会希望遍历一个集合中的元素.例如,显示集合中的每个元素.一般遍历数组都是采用for循环或者增强for,这两个方法也可以用在集合框架,但是还有一种方法是采用迭代器遍历集合框架,它是一个对象 ...
- Leetcode 312.戳气球
戳气球 有 n 个气球,编号为0 到 n-1,每个气球上都标有一个数字,这些数字存在数组 nums 中. 现在要求你戳破所有的气球.每当你戳破一个气球 i 时,你可以获得 nums[left] * n ...
- HDU1757-A Simple Math Problem,矩阵快速幂,构造矩阵水过
A Simple Math Problem 一个矩阵快速幂水题,关键在于如何构造矩阵.做过一些很裸的矩阵快速幂,比如斐波那契的变形,这个题就类似那种构造.比赛的时候手残把矩阵相乘的一个j写成了i,调试 ...
- Oracle臨時表空間過大問題解決
查詢資料庫伺服器時,發現資料庫伺服器磁片使用空間達到了98%,分析總共的資料檔案也不可能達到如此大,經過查詢發現原來臨時表空間的使用方式達到了 32G,導致磁碟空間使用緊張.搜索了相應的文檔與資料後, ...
- [HDU2896]病毒侵袭(AC自动机)
传送门 题目中文描述,赞! 除了val记录id以外就是模板. 注意:每次数组都要清0.0 ——代码 #include <cstdio> #include <queue> #in ...
- CodeForces - 462B Appleman and Card Game
是一道简单题 将字母从个数多到小排序 然后 再按题目算法得到最多 但是注意 数据类型声明 money要为long long #include <iostream> #include < ...
- HUNAN 11567 Escaping (最大流)
http://acm.hunnu.edu.cn/online/?action=problem&type=list&courseid=0&querytext=&pagen ...