轉載:http://blog.csdn.net/you_and_me12/article/details/7959349java
apk文件使用解壓工具就能看到drawable等資源,可是有些遊戲中的圖片資源倒是沒法看到的。web
這個問題探索了許久……工具
【1】圖片資源不放置在drawable文件下,放在assets中(可是解壓apk,一樣能看到圖片資源),如下說說使用方法。加密
分析:Ⅰ)當圖片資源放在drawable中的時候,能有相應的Id去解析: BitmapFactory.decodeResource(res, id)spa
若是放置在assets下,就須要根據文件的名字去解析(Android提供AssetManager)。.net
Ⅱ)能夠本身創建多層目錄,方便管理。code
Ⅲ)這樣的解析過程,耗費的時間要比根據Id解析要多(手機愈來愈智能,這點時間基本看不出來)。orm
代碼:blog
/** * 從Assets中讀取圖片 * @param fileName :assets根目錄下 "a.png",有子文件夾的 "abc/a.png" * @return */ public static Bitmap getImageFromAssets(Context context, String fileName) { Bitmap image = null; AssetManager am = context.getResources().getAssets(); try { InputStream is = am.open(fileName); image = BitmapFactory.decodeStream(is); is.close(); } catch (IOException e) { e.printStackTrace(); } return image; }
【2】圖片資源打包在jar下,而後導入工程(可是解壓apk,一樣能看到圖片資源)遊戲
分析:使用過一下第三方的jar包,在apk解壓後是看不到的,嘗試看看。最終發現jar包中的assets文件在apk中可見了。
Step1:打包jar
工程->右鍵->Export->Java/jar file->選擇須要打包的src 和 assets(以下圖)
Step2:解讀assets中的圖片,同【1】
Step3:打包apk,而後發現jar包中的assets和當前工程的assets合併了!
【3】圖片資源加密,而後在assets文件下讀取(能夠實現資源保護,可是貌似比較耗時)
分析:經過某種方式對圖片預先加密,而後在Android程序中解密,在轉換成Bitmap。
可能別的應用程序就是這樣作的吧,哪位大神有妙招,給介紹一下吧!(下面介紹一下簡單方法)
Step1:加密,採用文件流方式,讀取資源,而後修改,最後生成文件(隨便格式均可以,就不能知道是圖片了)
Ⅰ)每隔多少個字節添加一個指定的字節
Ⅱ)每隔多少個字節,交換字節(代碼示例)
public class KMD1 { public static void encrypt(String filePath){ byte[] tempbytes = new byte[5000]; try { InputStream in = new FileInputStream(filePath); OutputStream out = new FileOutputStream(filePath.subSequence(0, filePath.lastIndexOf("."))+"2.jpg") while (in.read(tempbytes) != -1) {//簡單的交換 byte a = tempbytes[0]; tempbytes[0] = tempbytes[1]; tempbytes[1] = a; out.write(tempbytes);//寫文件 } } catch (IOException e) { e.printStackTrace(); } } public static void main(String[] args){ KMD1.encrypt("D:/a.jpg"); } }
/** * 從Assets中讀取圖片 * @param fileName * @return */ public static Bitmap getImageFromAssets(Context context, String fileName) { Bitmap image = null; AssetManager am = context.getResources().getAssets(); try { InputStream is = am.open(fileName); byte[] buffer = new byte[1000000];//足夠大 is.read(buffer); for(int i=0; i<buffer.length; i+= 5000){//與加密相同 byte temp = buffer[i]; buffer[i] = buffer[i+1]; buffer[i+1] = temp; } image = BitmapFactory.decodeByteArray(buffer, 0, buffer.length); is.close(); } catch (IOException e) { e.printStackTrace(); } return image; }
【3】使用setPixel()和getPixel()對每一個像素點進行加密,而後在使用的時候在還原
分析:經過Bitmap.getPixel(x, y)獲得color值,對color的rgb值加密操做,而後setPixel(x,y,color)
Step1:懶得寫了,直接貼代碼:
注意:bitmap必定要copy一份,而後第二個值爲true才能對其setPixel,否則會報錯的;代碼中的encrypt和decrypt就是你加密解密過程;
嚴重問題:對bitmap setPixel而後在getPixel,color值居然不是set的值,有誤差,不知道爲何。有能解決這個問題的,請留言一下。
Bitmap temp_bitmap = image.copy(Bitmap.Config.ARGB_8888, true); int width = temp_bitmap.getWidth(); int height = temp_bitmap.getHeight(); int[] pixels = new int[width * height]; //temp_bitmap.getPixels(pixels, 0, width, 0, 0, width, height); for(int i = 0; i < height; i++) { for(int j = 0; j < width; j++) { int color = temp_bitmap.getPixel(i, j); int r = Color.red(color); int g = Color.green(color); int b = Color.blue(color); int alpha = Color.alpha(color); //if(alpha != 0) { r = encrptyRGB(r, 2*(i*j)); g = encrptyRGB(g, 4*(i*j)); b = encrptyRGB(b, 6*(i*j)); color = Color.argb(alpha, r, g, b); pixels[width * i + j] = color; //temp_bitmap.setPixel(i, j, color); } } } temp_bitmap.setPixels(pixels, 0, width, 0, 0, width, height); for(int i = 0; i < height; i++) { for(int j = 0; j < width; j++) { int color = temp_bitmap.getPixel(i, j); int r = Color.red(color); int g = Color.green(color); int b = Color.blue(color); int alpha = Color.alpha(color); //if(alpha != 0) { r = decryptRGB(r, 2*(i*j)); g = decryptRGB(g, 4*(i*j)); b = decryptRGB(b, 6*(i*j)); color = Color.argb(alpha, r, g, b); pixels[width * i + j] = color; //temp_bitmap.setPixel(i, j, color); } } } temp_bitmap.setPixels(pixels, 0, width, 0, 0, width, height); return temp_bitmap;