一、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;
}

二、色彩深度

  色彩深度(Depth of Color),色彩深度又叫色彩位数。视频画面中红、绿、蓝三个颜色通道中每种颜色为N位,总的色彩位数则为3N,色彩深度也就是视频设备所能辨析的色彩范围。目前有18bit、24bit、30bit、36bit、42bit和48bit位等多种。24位色被称为真彩色,R、G、B各8bit,常说的8bit,色彩总数为1670万,如诺基亚手机参数,多少万色素就这个概念。
灰阶
  什么又是灰阶呢?通常来说,液晶屏幕上人们肉眼所见的一个点,即一个像素,它是由红、绿、蓝(RGB)三原色组成的。每一个基色,其背后的光源都可以显现出不同的亮度级别。而灰阶代表了由最暗到最亮之间不同亮度的层次级别。把三基色每一个颜色从纯色(如纯红)不断变暗到黑的过程中的变化级别划分成为色彩的灰阶,并用数字表示,就是最常见的色彩存储原理。这中间层级越多,所能够呈现的画面效果也就越细腻。以8bit 为例,我们就称之为256灰阶。
8bit 10bit 12bit 14bit 16bit
    在数字信息存贮中,计算设备用2进制数来表示,每个0或1就是一个位(bit)。 假设1代表黑、0代表白,在黑白双色系统中最少有2bit。单基色为nbit,画面位数就为2 ⁿbit,位数越大,灰度越多,颜色也越多,彩色系统中同理。视频画面10bit含义就是画面能以10为二进制数的数量控制色彩层次(即灰阶)。通常8bit相当于256级灰阶——即常说得24位真彩色;而10bit就相当于1024级灰阶。三基色混合成彩色,增加1 bit就意味色彩数增加8倍。10bit就相当于1024的三次方——1073741824,约为10.7亿色。远大于8bit的1670万色。
三、
        选择一个极端的例子,找个蓝天占据大部分画面的例子。Raw在CS调整完后,存储Tiff,下面有位数选择,8bit/16bit,各选一次,分开两个文件。各自打开,然后调整,色阶,把暗部和高光压缩尽量小的可见范围。调完相同的参数,大家再看看各自的直方图,注意蓝天部分的区别。。
       有人就说了,我们讨论的是12bit和14bit,你讨论8bit和16bit,这靠谱吗?
       这个例子是说明色深位数的区别。8-12-14-16的区别就在连续性和宽容度上。靠不靠谱自己琢磨吧。不要再说这个是数字游戏了,这个bit不是这么傻瓜地自动把你的文件增大,是件很靠谱的事情。
四、
       14bit意义重大。
       将RAW转换为JPG时,14bit比12bit有更大的“裁剪空间”。大家都知道像素数多便于几何裁剪,同样的,灰度级多便于“灰度裁剪”。

Android 图片显示的更多相关文章

  1. Android ListView滑动过程中图片显示重复错乱闪烁问题解决

    最新内容建议直接访问原文:Android ListView滑动过程中图片显示重复错乱闪烁问题解决 主要分析Android ListView滚动过程中图片显示重复.错乱.闪烁的原因及解决方法,顺带提及L ...

  2. Android ImageView显示本地图片

    Android ImageView 显示本地图片 布局文件 <?xml version="1.0" encoding="utf-8"?> <R ...

  3. Android相机、相册获取图片显示并保存到SD卡

    Android相机.相册获取图片显示并保存到SD卡 [复制链接]   电梯直达 楼主    发表于 2013-3-13 19:51:43 | 只看该作者 |只看大图  本帖最后由 happy小妖同学 ...

  4. Android ListView分页加载时图片显示问题

    场景:Android ListView需要分页加载,每个item中会有图片,图片又是从网络下载的. 问题:在滑动加载下一页时,上一页的图片明明已经下载完成了,但是无法显示出来. Bug重现: 1,加载 ...

  5. app开发历程——android手机显示服务器端图片思路

    以前自己都不知道怎么去显示服务器端的图片,还好在apkbus论坛上找到一个特别简单的例子.虽然一天天忙忙碌碌,但是自己内心其实有一种想逃的心里,说不定哪天就会冒出来. 1.首先服务器端图片 这里的Im ...

  6. Android中显示gif动态图片

    在android中显示一个静态图片比如png jpg等等都很方便,但是如果要显示一个gif 动态图片就需要进行一些处理. 本文是采用自定义view 然后进行重新onDraw方法来实现 首先自定义Vie ...

  7. IT观察】网络通信、图片显示、数据库操作……Android程序员如何利用开源框架

    每个Android 程序员都不是Android应用开发之路上孤军奋战的一个人,GitHub上浩如烟海的开源框架或类库就是前人为我们发明的轮子,有的轮子能提高软件性能,而有的轮子似乎是以牺牲性能为代价换 ...

  8. android 图片解码显示流程

    版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/jingxia2008/article/details/32327699 问题来源 android 能 ...

  9. Android图片处理:识别图像方向并显示

    在Android中使用ImageView显示图片的时候发现图片显示不正.方向偏了或者倒过来了. 解决问题非常自然想到的分两步走: 1.自己主动识别图像方向,计算旋转角度. 2.对图像进行旋转并显示. ...

随机推荐

  1. js简单固定table表头及css问题分析。

    <head> <meta name="viewport" content="width=device-width" /> <tit ...

  2. 一篇顺手的Ubuntu+caffe配置笔记

    主要参考: https://github.com/lbzhang/dl-setup http://ouxinyu.github.io/Blogs/20151108001.html http://www ...

  3. Scala AOP

    trait Action { def doAction } trait TBeforeAfter extends Action { abstract override def doAction { p ...

  4. [Centos] mod_wsgi 安装流程以及遇到问题解决办法。apxs: command not found 或 Sorry, Python developer package does not appear to be installed.

    前提: Centos 系统, apache 已安装, python 已安装. 1. 首先下载mod_wsgi-3.5.tar.gz 下载地址:https://code.google.com/p/mod ...

  5. OOP in JS - Inheritance

    Summary You cause a class to inherit using ChildClassName.prototype = new ParentClass();. You need t ...

  6. APICloud界面间跳转

    UZModule提供属性controller,可通过该控制器对目标控制器进行push或者present操作. // push[self.viewController.navigationControl ...

  7. When Hybrid Cloud Meets Flash Crowd: Towards Cost-Effective Service Provisioning--INFOCOM 2015

    [标题] [作者] [来源] [对本文评价] [why] 存在的问题 [how] [不足] assumption future work [相关方法或论文] [重点提示] [其它]

  8. JavaScript eval() 为什么使用eval()是一个坏主意 什么时候可以使用eval()

    ---------------------------------------------------------------------------------------------------- ...

  9. MySQL5.5.28启动错误 The server quit without updating PID file

    今天重新安装了一次 MySQL5.5.28 ,但启动的时候老是报错 Starting MySQL.. ERROR! The server quit without updating PID file ...

  10. kali Rolling 安装QQ

    ------------------------------------------------------------------- 环境: kali Rolling   64位 所需软件包: Wi ...