标签归档:Programming

Android中对图像进行Base64编码

首先我们来看看维基百科是怎么定义的这个概念的。

Base64 is a generic term for a number of similar encoding schemes that encode binary data by treating it numerically and translating it into a base 64 representation. The Base64 term originates from a specificMIME content transfer encoding.

Base64 encoding schemes are commonly used when there is a need to encode binary data that needs be stored and transferred over media that are designed to deal with textual data. This is to ensure that the data remains intact without modification during transport. Base64 is used commonly in a number of applications including email via MIME, and storing complex data in XML.

当然我们对于概念可以不做过多的理会,只要知道这是一种编码方式,设计用来进行数据传输,而且要不易为人读懂,也就是为了加密用的设计的目的是用文本字符串来传输二进制数据(经麦壳童鞋和KongQue童鞋二人提醒后,更正)。至于他的算法实现,我们可以Google出来很多中成熟的算法。

我选用了这个网站上提供的源码,测试之后暂时还没有发现问题,并且该源码的作者将版权完全放弃了,无需任何的License授权,也不怕License感染,拿过来用就是了,作者只是希望使用的人如果发现问题可以反馈给他,如果能参与进来一起解决那是更好。

Android SDK2.2之后提供了Base64编码相关的API类Base64,不过鉴于开发的程序需要向下兼容,我想大部分的程序还是需要自己实现或者寻求第三方的实现来解决该问题。下面我们来一步步看看如何将图片编码成一个Base64编码的字符串进行传输。

任何图像到了程序中都需要解码成为Bitmap来进行绘制(不论是显示的解码还是系统在API中帮的忙),解码之后的Bitmap就是一张位图也就是一个byte数组,在Android中Bitmap有compress(Bitmap.CompressFormat format, int quality, OutputStream stream)这个方法,该方法可以将Bitmap重新压缩存储为别的格式,可以是PNG/JPG文件,或者是ByteArrayOutputStream输出。

public static String getBitmapStrBase64(Bitmap bitmap){
    ByteArrayOutputStream baos = new ByteArrayOutputStream(); 
    bitmap.compress(CompressFormat.PNG, 100, baos);
    byte[] bytes  = baos.toByteArray();
    return Base64.encodeBytes(bytes);
}

这就是获取位图Base64编码的代码,同理也可以将Base64编码字符串转化为Bitmap对象

public Bitmap getBitmap(){
        try {
            byte[] bitmapArray;
            bitmapArray = Base64.decode(iconBase64);
            return BitmapFactory.decodeByteArray(bitmapArray, 0, bitmapArray.length);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

以上就是所有的代码实现了,比较简单,效率还不错。

初窥Android游戏开发

最近一个月的时间熟悉了一下Android平台上的游戏开发流程.因为游戏相对于软件来说还是有一定区别的,可能跟系统提供的大部分API关系并不是特别的大,主要使用的可能就是系统的图形和声音,以及影像相关的API了。

最初学习Android,只是跟着官方提供的文档和示例一个个地去抄,抄完了之后自己写,主要就学习了一下Activity的一些简单的知识,主要是Activity之间的通信,Activity的生命周期,以及Activity Stack等等一些。对于游戏开发几乎是0,因为之前自己做的工作主要是Java中间件开发,使用的技术是JNI,并没有太多的接触过业务逻辑,对于功能的实现和集成还是非常的生疏。此次游戏开发委实长了不少的经验啊。从对Android的基础绘图API和线程的控制,状态机的维护,资源的释放等等,不一而足啊。

下面列举一下,近来学习的一些方面:

  • SurfaceView的使用,我想这大概是Android为了游戏开发人员做的一个特殊的基类,通过继承该类,并实现SufaceHolder.CallBack接口便可,通过SurfaceHolder.lockCanvas()获取画布,之后的各种绘制操作均可在当前画布上执行(Canvas.draw()系列方法),之后使用SurfaceHolder.unlockCanvasAndPost(Canvas canvas)方法,将绘制刷新到屏幕。
  • Thread.sleep(long millis)方法中的millis是跟系统时钟相关的,并不是真正的实际的时长,所以在这里需要做一个换算,使用多次Thread.sleep(long millis)方法来探测当前的换算比是多少,然后使用自己所需要的时长乘以该比值,设置给sleep()方法,才能得到正确的效果。
  • 关于游戏配置资源的读写,在游戏中,通常会有几种资源文件,图像,声音,XML关卡数据,游戏运行时配置文件(ini/properties).声音,图像,XML文件通常只需要使用系统默认的资源管理方式即可,如果程序中不需要使用文件名来进行配置的话,但是如果需要使用“logo.png”类似的名字来进行配置的话,可能系统提供的通过资源预编译后ID的方式就并不是那么尽如人意了,通常这种情况下,可以通过AssetManager.open(String fileName)来打开assets目录下的文件,可以使用子目录只是fileName就应该是”subfolderName/filename”这种格式了。在写入配置文件时,Android 为每个应用程序都提供了一个私有目录,”file://data/data/fullpackagename/files/”目录(fullpackagename是当前应用程序所在的包名,例如com.xixun.games),通过调用Context.openFileInput(String name, int mode)和Context.openFileOutput(String name, int mode)来获取输入和输出流。
  • Bitmap相关方法将可能导致error:OutOfMemory,这个确实是在手持设备上的一个问题,Android Dalvik VM 的实现中,只给了每个应用程序8M(该数据从互联网查得,并未验证是否属实)的内存用于图形,当程序为Bitmap对象申请超过8M内存时,将会抛出该错误(不是异常)并退出程序,并没有什么非常好的方法一定能帮你解决这个问题,通常我们应该养成一种编程行为习惯,那就是在Bitmap不再使用的时候立刻将资源回收(调用Bitmap.recyle()方法),因为Bitmap的实现是系统级别的API,VM对这种对象的管理并不会那么尽如人意,所以最好还是程序自身来管理,否则在后续的开发中,如果再次加入更大的资源将极为频繁地出现该问题。那么什么时候可能会出现该问题呢?8M的内存,我什么时候可能知道内存快要用了呢?对,你不知道,我也不知道,不过我们要预防,而且自己在编程时也可以简单的计算一下,如果你使用png图片的话,1.5M,到了程序中,如果你将所有的png均转化成了Bitmap对象,那么你的程序中使用的内存就至少会使用4.5M的内存。而且如果图片还带透明效果的话,那么就可能是6M的内存了。

以上就是近期的一些学习总结。下次将分享一个关于Android应用程序访问网络的问题。