Android程序开发如何处理图像格式类及图像转换
在Android程序开发过程中,明确哪些图像格式类(ImageFormat、PixelFormat及BitmapConfig等)及图像(JPG、PNG及BMP等)的转换方式非常重要,在以后的程序开发过程中会起到非常重要的作用。在一个项目开发过程中一款软件的开发和图像处理有着密切的关系,特别是在移动应用程序,在视觉效果等方面起到至关重要的作用,因为这关系到用户体验度。下面通过代码实例给大家分享下:
关于图像格式类,介绍以下三个:ImageFormat、PixelFormat及BitmapConfig。
1、ImageFormat(android.graphics.ImageFormat),格式参数有以下几种:
intJPEG,Encodedformats,常量值:256(0x00000100)
intNV16,YCbCrformat,usedforvideo,16(0x00000010)
intNV21,YCrCbformatusedforimages,whichusestheNV21encodingformat,常量值:17(0x00000011)
intRGB_565,RGBformatusedforpicturesencodedasRGB_565,常量值:4(0x00000004)
intUNKNOWN,常量值:0(0x00000000)
intYUY2,YCbCrformatusedforimages,whichusesYUYV(YUY2)encodingformat,20(0x00000014)
intYV12,AndroidYUVformat,Thisformatisexposedtosoftwaredecodersandapplications
YV12isa4:2:0YCrCbplanarformatcomprisedofaWxHYplanefollowedby(W/2)x(H/2)CrandCbplanes
解释总是英文的最通俗易懂,这里就不献丑翻译了。用法举例,在构建ImageReader类的对象时,会用到ImageFormat类的图像格式对象。如
ImageReaderimageReader=ImageReader.newInstance(width,height,ImageFormat.RGB_565,2);
imageReader对象表示其缓存中最多存在宽高分别为width和height、RGB_565格式的图像流两帧。
在需求中用哪一种图像格式,要视实际情况而定,后面的类似。
2、PixelFormat(android.graphics.PixelFormat),格式参数有以下几种:
intA_8,常量值:8(0x00000008)
intJPEG,常量值:256(0x00000100),constant,已声明不赞成使用,useImageFormat.JPEGinstead.
intLA_88,常量值:10(0x0000000a)
intL_8,常量值:9(0x00000009)
intOPAQUE,常量值:-1(0xffffffff),Systemchoosesanopaqueformat(noalphabitsrequired)
intRGBA_4444,常量值:7(0x00000007)
intRGBA_5551,常量值:6(0x00000006)
intRGBA_8888,常量值:1(0x00000001)
intRGBX_8888,常量值:2(0x00000002)
intRGB_332,常量值:11(0x0000000b)
intRGB_565,常量值:4(0x00000004)
intRGB_888,常量值:3(0x00000003)
intTRANSLUCENT,常量值:-3(0xfffffffd),Systemchoosesaformatthatsupportstranslucency(manyalphabits)
intTRANSPARENT,常量值:-2(0xfffffffe),Systemchoosesaformatthatsupportstransparency(atleast1alphabit)
intUNKNOWN,常量值:0(0x00000000)
intYCbCr_420_SP,常量值:17(0x00000011),constant已声明不赞成使用useImageFormat.NV21instead
intYCbCr_422_I,常量值:20(0x00000014),constant已声明不赞成使用useImageFormat.YUY2instead
intYCbCr_422_SP,常量值:16(0x00000010),constant已声明不赞成使用useImageFormat.NV16instead
注意,有四种图像格式已被声明不赞成使用,可以用ImaggFormat相对应的格式进行代替。由此可知,两种图像格式之间存在相通之处。用法举例,让窗口实现渐变的效果,如
getWindow().setFormat(PixelFormat.RGBA_8888);
补充说明:RGBA_8888为android的一种32位颜色格式,R、G、B、A分别用八位表示,Android默认的图像格式是PixelFormat.OPAQUE,其是不带Alpha值的。
3、Bitmap.Config(Android.graphics.Bitmap内部类)
Possiblebitmapconfigurations。Abitmapconfigurationdescribeshowpixelsarestored。Thisaffectsthequality(colordepth)aswellastheabilitytodisplaytransparent/translucentcolors。(
官网介绍,大致意思是说:影响一个图片色彩色度显示质量主要看位图配置,显示图片时透明还是半透明)。
ALPHA_8:Eachpixelisstoredasasingletranslucency(alpha)channel。(原图的每一个像素以半透明显示)
ARGB_4444:ThisfieldwasdeprecatedinAPIlevel13。Becauseofthepoorqualityofthisconfiguration,itisadvisedtouseARGB_8888instead。(在API13以后就被弃用了,建议使用8888)。
ARGB_8888:Eachpixelisstoredon4bytes。Eachchannel(RGBandalphafortranslucency)isstoredwith8bitsofprecision(256possiblevalues)。Thisconfigurationisveryflexibleandoffersthebestquality。Itshouldbeusedwheneverpossible。(每个像素占4个字节,每个颜色8位元,反正很清晰,看着很舒服)。
RGB_565:Eachpixelisstoredon2bytesandonlytheRGBchannelsareencoded:redisstoredwith5bitsofprecision(32possiblevalues),greenisstoredwith6bitsofprecision(64possiblevalues)andblueisstoredwith5bitsofprecision。(这个应该很容易理解了)。
用法举例,构建Bitmap对象时,会用到BitmapConfig类图像格式对象,如:
Bitmapbitmap=Bitmap.createBitmap(width,height,Bitmap.Config.RGB_565)
下面来看各种类型图像之间的转换都有哪些方法、差异及共同点。
1、YUV转JPG
查阅到的资料大部分是把Yuv图像数据通过数学运算得到每个像素点的RGB编码,存入Bitmap对象,再调用Bitmap类自带的压缩方法生成JPG图片。这种方法效率极低,一张480x320分辨率的图片有20万个字节,因此运算需要经过20万次循环。其实android.graphics包下面有一个YuvImage类,可以将数据直接导入:
YuvImageimage=newYuvImage(data,ImageFormat.NV21,IMG_WIDTH,IMG_HEIGHT,null);
前面两个参数决定了数据源与图像格式,后面单个参数就不解释了。
而YuvImage类正好有一个compressToJPEG(Rectrect,inti,OutputStream)方法,可以直接将数据保存在JPG文件的输出流中。
2、PNG转Bitmap
byte[]data=null; FilepngImage=null; BufferedOutputStreamstream=null; try{ pngImage=newFile(outputFile);//outputFile为png图像名称 FileOutputStreamfstream=newFileOutputStream(pngImage); stream=newBufferedOutputStream(fstream); stream.write(data); }catch(Exceptione){ e.printStackTrace(); }finally{ if(stream!=null){ try{ stream.close(); }catch(IOExceptione){ e.printStackTrace(); } } } Bitmapbitmap=BitmapFactory.decodeByteArray(data,0,data.length);
如果通过资源(drawable)的形式,那就方便地多,只需要一句话。
Bitmapbmp=BitmapFactory.decodeResource(getResources(),R.drawable.icon);
虽然没有华丽的算法,但效果不错哦,就是想改变图像属性时得另外实现。
3、ARGB转Bitmap
BitmapbitmapOrg=BitmapFactory.decodeByteArray(rawData,0,rawData.length); BitmapbitmapNew=bitmapOrg.copy(Config.ARGB_8888,true); if(bitmapNew==null) return; for(inti=0;i<bitmapNew.getWidth();i++) { for(intj=0;j<bitmapNew.getHeight();j++) { intcol=bitmapNew.getPixel(i,j); intalpha=col&0xFF000000; intred=(col&0x00FF0000)>>16; intgreen=(col&0x0000FF00)>>8; intblue=(col&0x000000FF); intgray=(int)((float)red*0.3+(float)green*0.59+(float)blue*0.11); intnewColor=alpha|(gray<<16)|(gray<<8)|gray; } } sendMsg(bitmapNew); Filefile=newFile(Environment.getExternalStorageDirectory()+File.separator+"gray"+number+".jpg"); OutputStreamout; try{ out=newFileOutputStream(file); if(bitmapNew.compress(Bitmap.CompressFormat.JPEG,100,out)) out.close(); }catch(FileNotFoundExceptione){ e.printStackTrace(); }catch(IOExceptione){ e.printStackTrace(); }
以上全部内容就是在Android程序开发过程中处理图像格式类及图像转换的方法,需要注意的是,在代码中做了灰度处理,若想得到彩色图,分别对Bitmap图像R、G、B三通道赋值。希望大家能够喜欢。