傲嬌Android二三事之天不長地不久的Bitmap.compress

來源:互聯網
上載者:User

話說天下分久必合,合久必分。大諾王朝內閣首輔康培凱康大學士,剛愎自用,固步自封,不思進取,致使天下群雄並起。亂世之中,世家門閥Apple,微軟盡攬朝中精英於門下。而新進貴族Google則營前插著兩面大旗,只見左邊那面用西文寫著“I am free”,右面則用漢字寫著“你懂的”。至此,江湖好漢莫不相投與此。在這個修道不如修Bug的年代,貧道也只有順應時代的潮流,開始了兩點一線的Android開發碼工生活。

雖然Android秉承了太祖的團結一切可以團結的力量平民哲學思想,但是他終歸出生於貴族家庭。帶著一點小傲嬌,有點不接地氣兒。

話說,一個風和日麗的早春上午,貧道剛結束了一個編輯圖片功能的階段開發,在QQ上和眾道友們激揚文字,指點江山,縱談當前天下大勢。談到精彩之處,貧道不禁輕搖手中免費發放的時代報,頗有當年武侯隆中對的氣勢,好不得意。突然叮噹一聲,只見螢幕右下角,彈出個郵件提示框,貧道一看是一封Bug報告信。頓時,剛才的好心情一鬨而散,然後很不情願地點開了報告連結,只見上面寫著Image is destroyed。貧道頭上一陣黑線,用人類的正常思維實在想不出Image is destroyed的是個什麼狀況。還好該測試人士給出了一張展示bug的圖片,點進去一看,又是一陣惡寒。只見滿屏的馬賽克充斥其中,貧道暗想,雖然是測試,也不能這樣假公濟私,蹭機瀏覽收整合人專用圖片。而且這得多暴露啊,滿屏的馬賽克,想到這貧道暗暗鄙視了一下這個測試人員,好歹拿一張馬賽克美女圖啥的,給大家樂一下。獨樂樂,不如眾樂樂嘛。此時貧道故作鎮定地向測試員問起了該bug的情況,結果卻得到了一個驚人的訊息,此馬賽克並非天然形成,而是經過了圖片的載入,編輯,儲存,再載入,編輯,儲存,如此大小周天往複幾次,就成了這個效果。聽到這,貧道暗歎連連,趕忙拿了測試圖片,開始找尋原因。

回到座位點開圖片一看,是一個只比呂布智商高了20的傢伙,號稱只吃涮羊肉的灰太狼像(見圖1)。在貧道旋轉,上下左右顛倒,剪下等一系列的操作後,的確一層似曾相識的薄馬賽克浮現了出來(見圖2)。

       

圖1                                                                                           圖2

難道是圖片繪製時不夠精確?根據平常玩遊戲的經驗,調用了Paint的setAntiAlias反鋸齒函數來提高繪畫品質。然後籌措滿志的按下了Run,但是殘酷的現實打破了貧道妄圖速戰速決的期望。馬賽克君如同小強附體,頑強的生存了下來。

貧道再次審視了代碼,又做出一個判斷,是否是圖片旋轉或者上下左右顛倒時,座標移動的誤差積累所引起的呢?在忍痛割捨了旋轉和顛倒功能後,再一次Run了下程式,濤聲依舊。

難道是圖片的顏色位元問題,但一看代碼,都是四個8(Config.ARGB_8888),好吉利的設定。

常言說的好,欲使其滅亡,必先使其瘋狂。貧道重新寫了個測試程式(見以下的程式碼)。屏蔽了所有的編輯效果,只保留了載入和儲存。在惡狠狠地按下了Run後,貧道的世界觀開始崩潰了。馬賽克君巋然不動,好似老中醫的小廣告似的牢牢的貼在了圖片上。

MainActivity.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="match_parent"    android:layout_height="match_parent"    tools:context=".MainActivity" >        <ImageView        android:id="@+id/img"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:scaleType="fitCenter"        /></RelativeLayout>

 MainActivity.java

package com.example.testcompress;import java.io.ByteArrayOutputStream;import java.io.File;import java.io.FileOutputStream;import android.os.Bundle;import android.app.Activity;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.graphics.Bitmap.CompressFormat;import android.view.Menu;import android.widget.ImageView;public class MainActivity extends Activity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);Bitmap bmp = BitmapFactory.decodeFile("/mnt/sdcard/wolf.jpg");for(int i = 0 ; i < 30 ; i++){ImageView mv = (ImageView)findViewById(R.id.img);mv.setImageBitmap(bmp);File file = null;try {file = new File("/mnt/sdcard/wolf_tmp.jpg");file.delete();ByteArrayOutputStream stream = new ByteArrayOutputStream();bmp.compress(CompressFormat.JPEG, 100, stream);FileOutputStream os = new FileOutputStream(file);os.write(stream.toByteArray());os.close();} catch (Exception ex) {file = null;}bmp = BitmapFactory.decodeFile("/mnt/sdcard/wolf_tmp.jpg");}}@Overridepublic boolean onCreateOptionsMenu(Menu menu) {// Inflate the menu; this adds items to the action bar if it is present.getMenuInflater().inflate(R.menu.activity_main, menu);return true;}}

貧道雙手撓頭,陷入了沉思中。就在漫天的飛屑鋪滿案頭的時候,貧道突然發現,灰太狼這貨居然是裸奔的,難道被SDK判斷為少兒不宜,需要做騎兵處理。於是立馬換成了老少皆宜的desert.jpg檔案(見圖3)。事實證明我們又一次低估了馬賽克君的無恥程度,這次滄桑無垠的沙漠獲得了和蒼老師一樣的待遇,漫天的馬賽克(見圖4)。

   

圖3                                                                                                          圖4

這時旁邊同事的電腦又傳來了“我相信真相只有一個”那熟悉的聲音。腦海裡頓時出現貌似忠良,實乃國賊的秦檜,嚴嵩,汪Data Replication System形象。漸漸這些名字逐漸匯聚為compress的字樣。沒錯最終的元兇就是這個貌似二師兄,實乃佛地魔的Bitmap.compress。在屢次的儲存中,由於jpg壓縮演算法的問題,隨著儲存次數的增加,導致像素丟失越來越嚴重,最後馬賽克化。再狡猾的狐狸還是鬥不過獵人,貧道對著網頁中的Google標誌,鄙視的朝下豎起了大拇指。

為了再踩上一萬隻腳,我又測試了下png格式(修改代碼如下)。同樣都是一個媽生的,PNG圖片幾乎無損(見圖5)。

MainActivity.java

protected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);Bitmap bmp = BitmapFactory.decodeFile("/mnt/sdcard/wolf.png");for(int i = 0 ; i < 30 ; i++){ImageView mv = (ImageView)findViewById(R.id.img);mv.setImageBitmap(bmp);File file = null;try {file = new File("/mnt/sdcard/wolf_tmp.png");file.delete();ByteArrayOutputStream stream = new ByteArrayOutputStream();bmp.compress(CompressFormat.PNG, 100, stream);FileOutputStream os = new FileOutputStream(file);os.write(stream.toByteArray());os.close();} catch (Exception ex) {file = null;}bmp = BitmapFactory.decodeFile("/mnt/sdcard/wolf_tmp.png");}}

 

圖5

所以在此,貧道友情提示一下,為了保持圖的還原度,在Android開發中請盡量使用PNG格式圖片,日本國圖片除外。同時也將此提示寫在了中午用過的餐巾紙上,裱糊後,與諸君共勉。

 

 

 

 

 

 

 

          
相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.