Android 图片显示
一、Android手机显示图片
若R、G、B每种颜色使用一个字节(8bit)表示,每幅图像可以有1670万种颜色;若R、G、B每种颜色使用两个字节(16bit)表示,每幅图像可以有10的12次方种颜色;
如果是灰度图像,每个象素用一个字节(8bit)表示,一幅图像可以有256级灰度;若每个象素用两个字节(16bit)表示,一幅图像可以有65536级灰度。
但是在Android手机上只能显示0-255的图像,所以在显示之前要做一下处理。
以pmd的模组为例,获取的灰度图片数据范围是 uint16_t grayValue; //!< 16-bit gray value,显示的时候,采取的方法是通过JNI直接上传int数组,然后通过imageview.setbitmap的方法进行显示。
for (int i = ; i < width * height; i++)
{
fillir[i]= data->points.at (i).grayValue/4;
if(fillir[i]>) fillir[i]=;
fillir[i] = fillir[i] | fillir[i] << | fillir[i] << | << ;
}
因为最后显示的只是8bit数据,所以需要对数据进行处理,比如
fillir[i] = fillir[i] | fillir[i] << 8 | fillir[i] << 16 | 255 << 24;
就是把四个八位二进制数(颜色的RGB三个值和透明度A)拼接成一个二进制数(32位)。
前八位表示透明度,往后的三个八位分别代表RGB。有点像字符串相连。 “<<”和“|”分别是按位左移和按位或。 255<<24:11111111变成111111110000...(24个0)
四个数移动完后,按位或运算,相同位有1就为1,全为0则为0。
但是输入的是16bit所以图像有些数值大于255,在右移之前需要/4,降低图像尺度。
fillir[i]= data->points.at (i).grayValue/4;
而且定义,大于255 的为255.这样输入的就是8bit图像了。
注意:为了Android能够显示图像,一定要做的就是
fillir[i] = fillir[i] | fillir[i] << 8 | fillir[i] << 16 | 255 << 24;将图像转换成ARGB,这样在Java层创建图像。
irImageBmp = Bitmap.createBitmap(width, height,Bitmap.Config.ARGB_8888);
升级讨论,图像转换问题:
16bit灰度图像映射到8bit显示
图像显示和打印面临的一个问题是:图像的亮度和对比度能否充分突出关键部分。这里所指的“关键部分”在 CT 里的例子有软组织、骨头、脑组织、肺、腹部等等。
技术问题:
o 显示器往往只有 8-bit, 而数据有 12- 至 16-bits。
o 如果将数据的 min 和 max 间 (dynamic range) 的之间转换到 8-bit 0-255 去,过程是个有损转换, 而且出来的图像往往突出的是些噪音。
针对这些问题,研究人员先提出一些要求 (requirements),然后根据这些要求提出了一些算法。这些算法现在都很成熟。
要求一:充分利用 0-255 间的显示有效值域
要求二:尽量减少值域压缩带来的损失
要求三:不能损失应该突出的组织部分
算法分析:
A. 16-bit 到 8-bit 直接转换:
computeMinMax(pixel_val, min, max); // 先算图像的最大和最小值
for (i = ; i < nNumPixels; i++)
disp_pixel_val[i] = (pixel_val[i] - min)*255.0/(double)(max - min);
这个算法必须有,对不少种类的图像是很有效的:如 8-bit 图像,MRI, ECT, CR 等等。
B. Window-leveling 算法: W/L 是专门为 CT 设计的。
原理很简单:CT 图像里不同组织的密度 (用 Hounsfield 单位) 是在固定的值域, 与具体设备和成像软件没有关系。因此,要看头颅时, 我们只需将头颅的值域转换到 0-255 就行了。
CT W/L 不讲头颅值域的 min 和 max, 而说 max - min (即 window_width) 和 (max+min)/2 (即 window_center)。
我们还可以用原来的公式,只是 min 和 max 的算法不一样。
// 先算图像的最大和最小值
min = (*window_center - window_width)/2.0 + 0.5;
max = (*window_center + window_width)/2.0 + 0.5;
for (i = ; i < nNumPixels; i++)
disp_pixel_val[i] = (pixel_val[i] - min)*255.0/(double)(max - min);
请注意,CT 图像必须先转换成 Hounsfield 值再做 window-level。 这个转换包括将多余高位 bits 变成 0 (clipping), 和用 recale slope 和 rescale intercept 来做单位转换。
HU[i] = pixel_val[i]*rescale_slope + rescale_intercept
C.非线性转换
我刚刚说的是将 min 和 max 间的数值线性转换到 0-255 之间。 如果 max - min 出来是个很大的数值,比如说 25500, 那就说每 100 原始密度会压缩成一个显示灰度。 这样的损失可能会很大。
因为人眼对灰度地反应式是非线性的,非线性转换可以解决一些问题。 常用算法有 log 和 gamma 两种。gamma 比较好调 gamma 值,因此用得比较多。
for (i = ; i < nNumPixels; i++)
disp_pixel_val[i] = 255.0 * pow(pixel_value[i]/(max-min), 1.0/gamma);
D. 有效值域:CT 的 Window-level 有标准的定义,请参看 “Practical CT Techniques", by Wladyslaw Gedroyc and Sheila Rankin, Springer-Verlag。最常用到的有 WW = 400, WL = 40 (实用许多部位); WW = 100, WL = 36 (头);WW = 3200, WL = 200 (骨头),等等。
补充几点:
o 在做任何转换时要注意有效灰度域外的数值的处理。
最好先用 int 而非 unsigned char 来算,再转入矩阵,以避免 overflow 和 underflow。
double dFactor = 255.0/(double)(max - min);
int nPixelVal;
for (i = ; i < nNumPixels; i++)
{
nPixelVal = (int) ((pixel_val[i] - min)*dFactor);
if (nPixelVal < )
disp_pixel_val[i] = ;
else if (nPixelVal > )
disp_pixel_val[i] = ;
else
disp_pixel_val[i] = nPixelVal;
}
o 做 window-level 时要注意 min 和 max 之外原始数据的处理
double dFactor, min, max;
int nPixelVal;
min = (*window_center - window_width)/2.0 + 0.5;
max = (*window_center + window_width)/2.0 + 0.5;
dFactor = 255.0/(double)(max - min);
for (i = ; i < nNumPixels; i++)
{
if (pixel_val[i] < min)
{
disp_pixel_val[i] = ;
continue;
}
if (pixel_val[i] > max)
{
disp_pixel_val[i] = ;
continue;
}
nPixelVal = (int)((pixel_val[i] - min)*dFactor); if (nPixelVal < )
disp_pixel_val[i] = ;
else if (nPixelVal > )
disp_pixel_val[i] = ;
else
disp_pixel_val[i] = nPixelVal;
}
二、色彩深度
有人就说了,我们讨论的是12bit和14bit,你讨论8bit和16bit,这靠谱吗?
这个例子是说明色深位数的区别。8-12-14-16的区别就在连续性和宽容度上。靠不靠谱自己琢磨吧。不要再说这个是数字游戏了,这个bit不是这么傻瓜地自动把你的文件增大,是件很靠谱的事情。
将RAW转换为JPG时,14bit比12bit有更大的“裁剪空间”。大家都知道像素数多便于几何裁剪,同样的,灰度级多便于“灰度裁剪”。
Android 图片显示的更多相关文章
- Android ListView滑动过程中图片显示重复错乱闪烁问题解决
最新内容建议直接访问原文:Android ListView滑动过程中图片显示重复错乱闪烁问题解决 主要分析Android ListView滚动过程中图片显示重复.错乱.闪烁的原因及解决方法,顺带提及L ...
- Android ImageView显示本地图片
Android ImageView 显示本地图片 布局文件 <?xml version="1.0" encoding="utf-8"?> <R ...
- Android相机、相册获取图片显示并保存到SD卡
Android相机.相册获取图片显示并保存到SD卡 [复制链接] 电梯直达 楼主 发表于 2013-3-13 19:51:43 | 只看该作者 |只看大图 本帖最后由 happy小妖同学 ...
- Android ListView分页加载时图片显示问题
场景:Android ListView需要分页加载,每个item中会有图片,图片又是从网络下载的. 问题:在滑动加载下一页时,上一页的图片明明已经下载完成了,但是无法显示出来. Bug重现: 1,加载 ...
- app开发历程——android手机显示服务器端图片思路
以前自己都不知道怎么去显示服务器端的图片,还好在apkbus论坛上找到一个特别简单的例子.虽然一天天忙忙碌碌,但是自己内心其实有一种想逃的心里,说不定哪天就会冒出来. 1.首先服务器端图片 这里的Im ...
- Android中显示gif动态图片
在android中显示一个静态图片比如png jpg等等都很方便,但是如果要显示一个gif 动态图片就需要进行一些处理. 本文是采用自定义view 然后进行重新onDraw方法来实现 首先自定义Vie ...
- IT观察】网络通信、图片显示、数据库操作……Android程序员如何利用开源框架
每个Android 程序员都不是Android应用开发之路上孤军奋战的一个人,GitHub上浩如烟海的开源框架或类库就是前人为我们发明的轮子,有的轮子能提高软件性能,而有的轮子似乎是以牺牲性能为代价换 ...
- android 图片解码显示流程
版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/jingxia2008/article/details/32327699 问题来源 android 能 ...
- Android图片处理:识别图像方向并显示
在Android中使用ImageView显示图片的时候发现图片显示不正.方向偏了或者倒过来了. 解决问题非常自然想到的分两步走: 1.自己主动识别图像方向,计算旋转角度. 2.对图像进行旋转并显示. ...
随机推荐
- 利用rabbit_mq队列消息实现对一组主机进行命令下发
目的: 利用rabbit_mq队列消息实现对一组主机进行命令下发 server: #!/usr/bin/env python3.5 # -*- coding:utf8 -*- import os,sy ...
- MAMP、wordpress安装
p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; text-align: center; font: 12.0px Helvetica } p.p4 { margin: ...
- token 小记
最近了解下基于 Token 的身份验证,跟大伙分享下.很多大型网站也都在用,比如 Facebook,Twitter,Google+,Github 等等,比起传统的身份验证方法,Token 扩展性更强, ...
- 【CSS】display: inline-block,内联元素
什么是内联元素? <CSS权威指南>中文字显示:任何不是块级元素的可见元素都是内联元素.其表现的特性是“行布局”形式,这里的“行布局”的意思就是说其表现形式始终以行进行显示.比如,我们设定 ...
- 【.NET】字符串处理
类名:DealString /// 1.截取字符串,最后加3个小数点 /// 2.获得指定Url的参数的string类型值 /// 3.判断数据类型 /// 4.过滤JS标记 /// 5.获取Chec ...
- pull类型消息中间件-消息消费者(二)
消费者的实例化 关于consumer的默认实现,metaq有两种: DefaultMQPullConsumer:由业务方主动拉取消息 DefaultMQPushConsumer:通过业务方注册回调方法 ...
- Centos7安装Docker 基于Dockerfile 搭建httpd运行环境
Centos7安装Docker 基于Dockerfile 搭建httpd运行环境 docker docker搭建 docker build 本文档完成目标内容如下 使用Docker搭建http服务器一 ...
- 【界面优化】使用viewpagerindicator添加下划线滑动动画
开源代码viewpagerindicator里面没有实现tab下划线切换过程中的移动动画,都是很突兀的多个fragement之间的切换,导致用户体验略差,google了下相关问题,发现一片博文: ht ...
- 淘淘商城_day02_课堂笔记
今日大纲 学习Nginx的使用 实现商品的管理 新增商品 查询商品列表 编辑商品 删除商品 上架和下架商品 学习nginx 开发阶段中的环境 开发环境:自己的电脑 测试环境:提供给测试人员使用的环境 ...
- CodeForces 702E Analysis of Pathes in Functional Graph
倍增预处理. 先看一下这张图的结构,因为出度都是$1$,所以路径是唯一的,又因为每个点都有出度,所以必然有环,也就是一直可以走下去. 接下来我们需要记录一些值便于询问: 设$t[i][j]$表示从$i ...