扫二维码与项目经理沟通
我们在微信上24小时期待你的声音
解答本文疑问/技术咨询/运营咨询/技术建议/互联网交流
#本文以Android api 22为基准
10年积累的成都网站设计、网站建设经验,可以快速应对客户对网站的新想法和需求。提供各种问题对应的解决方案。让选择我们的客户得到更好、更有力的网络服务。我虽然不认识你,你也不认识我。但先网站制作后付款的网站建设流程,更有潜江免费网站建设让你可以放心的选择与我们合作。
在android.graphics.PixelFormat中定义了如下几种(不含deprecated的)RGB格式:
名称 | 值 | 含义 |
RGBA_8888 | 1 | 透明通道和三个颜色通道都是8,可表达的色彩值最广,这是使用最广泛的格式 |
RGBX_8888 | 2 | 与RGBA_8888类似不过,透明通道的值永远为255 |
RGB_888 | 3 | 只有三个颜色通道,存储空间相对前两个较小。 |
Bitmap代表了解码后图片,可用于直接的绘制,Bitmap与一个native层的bitmap对应,使用完后,需要调用recyle函数回收native内存。
android.graphics.Bitmap类代表了java层可绘制实体的最后一步。从一整个页面,到某个view,在到drawable,最后都会汇集到Bitmap。
对于任何一个view来说,在onDraw()回调中,canvas都已经与一个bitmap绑定。
Bitmap类提供了对像素点操作的一些基本接口。
对于开发者来说,关于Bitmap需要的做得事情有,创建Bitmap,操作像素,压缩存储,序列化/反序列化等。
需要自己创建Bitmap时,有两种情况,一种是全新创建,另外一种是加载已有的图片。
对于第一种,可使用Bitmap.createBitmap(...)函数创建,然后使用Bitmap类的像素操作接口填充像素,或者结合Canvas进行更高级的绘制。
对于后一种,图片的来源无非是这几种:network,drawableX目录,assets目录,raw目录,本地持久化存储。所有的这些图片都可以通过android.graphics.BitmapFactory工具类加载,解码并创建为Bitmap。具体如下:
来源于本地存储 | BitmapFactory.decodeFile(String, Options)或者BitmapFactory.decodeFile(String) |
来源于drawableX的纯图片 | BitmapDrawable drawable = (BitmapDrawable) context.getDrawable(int picResId); // 注意这里的picResId必须指向一个纯图片Bitmap bitmap = drawable.getBitmap(); |
来源于一般的drawable | Bitmap.Config config = drawable.getOpacity() != PixelFormat.OPAQUE ? Bitmap.Config.ARGB_8888 : Bitmap.Config.RGB_565;Bitmap bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), config);Canvas canvas = new Canvas(bitmap);drawable.setBounds(0, 0, w, h);drawable.draw(canvas); |
来源于assets | 假如图片路径为:/assets/img/asset_img.pngBitmap bitmap = BitmapFactory.decodeStream(context.getResources().getAssets().open(“img/asset_img.png")) |
来源于raw | Bitmap bitmap = BitmapFactory.decodeStream(context.getResources().openRawResource(R.raw.raw_img)) |
操作像素
对于像素的操作可以通过Bitmap类自己提供的一些基本的操作接口,也可以通过canvas进行。后者提供了很多人性化的绘制方法,并且可以与很多android graphics框架中许多图形特效类结合使用,绘制出更加出彩的内容。这里只谈前者,后者会在其他文章中继续讨论。
getPixel(int x, int y) | 获取指定位置的像素色彩值 |
getPixels(int[] pixels, int offset, int stride, int x, int y, int width, int height) | 一次获取多个像素点,如果要获取多个像素,调用此方法比循环的调用getPixel()效率要高 |
setPixel(int x, int y) | 设置指定位置的一个像素 |
setPixels(int[] pixels, int offset, int stride, int x, int y, int width, int height) | 批量设置像素,对于同时设置多像素来说,该方法比循环调用setPixel()效率要高 |
copyPixelsToBuffer(Buffer dst) | 复制整个图片像素到一个buffer |
copyPixelsFromBuffer(Buffer src) | 用一个buffer中的像素覆盖当前bitmap中的像素 |
setPixels()和getPixels()参数中的stride代表了参数pixels一行的长度,我们可以把这两个方法看作是一个像素矩阵向另外一个像素矩阵投射的过程,两个矩阵可能大小不同。不管是setPixels()还是getPixels(),当位图像素的读取或设置需要换行时,pixels数组也需要”换行”,这时后者的换行就需要以stride为基准。这也是为甚stride要大于等于width的原因。具体可以看这篇文章:http://ranlic.iteye.com/blog/1313735
压缩存储
Bitmap.compress(CompressFormat format, int quality, OutputStream outStream),其中quality的值范围是[0, 100],0代表最低的质量最大的压缩。
序列化与反序列化
Bitmap实现了Parcelable接口,如果是用intnet进行数据传递,可以直接放到extra中。
如果是通过网络传输(这里不考虑需求的合理性,因为实际中很少有直接通过网络传输位图的,都是传输压缩后的图片),则需要调用copyPixelsToBuffer()。
我们在微信上24小时期待你的声音
解答本文疑问/技术咨询/运营咨询/技术建议/互联网交流