多多色-多人伦交性欧美在线观看-多人伦精品一区二区三区视频-多色视频-免费黄色视屏网站-免费黄色在线

國內最全IT社區平臺 聯系我們 | 收藏本站
阿里云優惠2
您當前位置:首頁 > 互聯網 > [Android] 給圖像添加相框、圓形圓角顯示圖片、圖像合成知識

[Android] 給圖像添加相框、圓形圓角顯示圖片、圖像合成知識

來源:程序員人生   發布時間:2014-11-13 08:58:42 閱讀次數:3189次

    前1篇文章講述了Android觸屏setOnTouchListener實現突破縮放、移動、繪制和添加水印,繼續我的"隨手拍"項目完成給圖片添加相框、圓形圓角顯示圖片和圖象合成的功能介紹.希望文章對大家有所幫助.

1. 打開圖片和顯示assets文件中圖片

    首先,對XML中activity_main.xml進行布局,通過使用RelativeLayout相對布局完成(XML代碼后面附).然后,在Mainctivity.java中public class MainActivity extends Activity函數添加代碼以下,添加點擊按鈕監聽事件:

//控件 private Button openImageBn; //打開圖片 private Button showImageBn; //顯示assets資源圖片 private Button showImageBn1; //模式1加成 private Button showImageBn2; //模式2加成 private Button roundImageBn; //圓角圖片 private ImageView imageShow; //顯示圖片 //自定義變量 private Bitmap bmp; //原始圖片 private final int IMAGE_OPEN = 0; //打開圖片 private Canvas canvas; //畫布 private Paint paint; //畫刷 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //打開圖片 openImageBn = (Button)findViewById(R.id.button1); imageShow = (ImageView) findViewById(R.id.imageView1); openImageBn.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { Intent intent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI); startActivityForResult(intent, IMAGE_OPEN); } }); if (savedInstanceState == null) { getFragmentManager().beginTransaction() .add(R.id.container, new PlaceholderFragment()) .commit(); } } //打開圖片 protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if(resultCode==RESULT_OK && requestCode==IMAGE_OPEN) { Uri imageFileUri = data.getData(); DisplayMetrics dm = new DisplayMetrics(); getWindowManager().getDefaultDisplay().getMetrics(dm); int width = dm.widthPixels; //手機屏幕水平分辨率 int height = dm.heightPixels; //手機屏幕垂直分辨率 try { //載入圖片尺寸大小沒載入圖片本身 true BitmapFactory.Options bmpFactoryOptions = new BitmapFactory.Options(); bmpFactoryOptions.inJustDecodeBounds = true; bmp = BitmapFactory.decodeStream(getContentResolver().openInputStream(imageFileUri), null, bmpFactoryOptions); int heightRatio = (int)Math.ceil(bmpFactoryOptions.outHeight/(float)height); int widthRatio = (int)Math.ceil(bmpFactoryOptions.outWidth/(float)width); //inSampleSize表示圖片占原圖比例 1表示原圖 if(heightRatio>1&&widthRatio>1) { if(heightRatio>widthRatio) { bmpFactoryOptions.inSampleSize = heightRatio; } else { bmpFactoryOptions.inSampleSize = widthRatio; } } //圖象真正解碼 false bmpFactoryOptions.inJustDecodeBounds = false; bmp = BitmapFactory.decodeStream(getContentResolver().openInputStream(imageFileUri), null, bmpFactoryOptions); imageShow.setImageBitmap(bmp); } catch(FileNotFoundException e) { e.printStackTrace(); } } //end if }

    上面點擊"打開"按鈕能實現打開圖片,而在講述為圖片添加邊框時,它其實就是通過兩張或多張圖片的合成實現的.
    在jacpy.may《Android圖片處理總結》文檔中建議圖片不要放在drawable目錄下,由于屏幕分辨率會影響圖片的大小.最好放在assets目錄里,它代表利用沒法直接訪問的原生資源(通常加載PNG透明圖實現邊框合成),只能以流的方式讀取并且小于1M.
    讀取assets文件夾中圖片的方法以下,首先手動添加PNG圖片至assets目錄,然后在omCreate函數中添加以下代碼:

//顯示assets中圖片 showImageBn = (Button)findViewById(R.id.button2); showImageBn.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { Bitmap bitmap = getImageFromAssets("image01.png"); imageShow.setImageBitmap(bitmap); } });
   再通過自定義函數getImageFromAssets實現獲得圖片"image01.png":

//獲得assets中資源并轉換為Bitmap private Bitmap getImageFromAssets(String fileName) { //Android中使用assets目錄寄存資源,它代表利用沒法直接訪問的原生資源 Bitmap imageAssets = null; AssetManager am = getResources().getAssets(); try { InputStream is = am.open(fileName); imageAssets = BitmapFactory.decodeStream(is); is.close(); } catch(IOException e) { e.printStackTrace(); } return imageAssets; }
   顯示效果以下圖所示:
            
   其中XML代碼以下:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/container" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="com.example.touchimagetest.MainActivity" tools:ignore="MergeRootFrame" > <!-- 底部添加按鈕 --> <RelativeLayout android:id="@+id/MyLayout_bottom" android:orientation="horizontal" android:layout_width="fill_parent" android:layout_height="50dp" android:layout_alignParentBottom="true" android:gravity="center"> <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="horizontal" android:layout_alignParentBottom="true" > <Button android:id="@+id/button1" android:layout_width="wrap_content" android:layout_height="match_parent" android:layout_weight="1" android:text="打開" /> <Button android:id="@+id/button2" android:layout_width="wrap_content" android:layout_height="match_parent" android:layout_weight="1" android:text="顯示" /> <Button android:id="@+id/button3" android:layout_width="wrap_content" android:layout_height="match_parent" android:layout_weight="1" android:text="邊框" /> <Button android:id="@+id/button4" android:layout_width="wrap_content" android:layout_height="match_parent" android:layout_weight="1" android:text="桃心" /> <Button android:id="@+id/button5" android:layout_width="wrap_content" android:layout_height="match_parent" android:layout_weight="1" android:text="圓形" /> </LinearLayout> </RelativeLayout> <!-- 頂部顯示圖片 --> <RelativeLayout android:id="@+id/Content_Layout" android:orientation="horizontal" android:layout_above="@id/MyLayout_bottom" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_alignParentTop="true" android:background="#000000" android:gravity="center"> <ImageView android:id="@+id/imageView1" android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_gravity="center_horizontal" /> </RelativeLayout> </RelativeLayout>

2. 添加相框與圖片合成

    然后開始完成圖片合成的工作,這里我采取兩種方法完成.繼續在onCreate函數中添加代碼:
//模式1合成圖片 showImageBn1 = (Button)findViewById(R.id.button3); showImageBn1.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { Bitmap bitmap = getImageFromAssets("image01.png"); addFrameToImage(bitmap); } });
   通過自定義函數addFrameToImage實現加載圖片合成.首先創建1個空的可變成圖對象,它的大小和配置與打開的圖象相同,隨后構建1個Canvas對象和1個Paint對象,在畫布上繪制第1個位圖對象,它成了合成操作的目標.
    現在設置Paint對象上的過渡模式,通過傳入1個定義操作模式的常量,實例化1個新的PorterDuffXfermode對象.然后在Canvas對象上繪制第2個位圖對象,并將ImageView設置為新的位圖對象.代碼以下:
//圖片合成1 private void addFrameToImage(Bitmap bm) //bmp原圖(前景) bm資源圖片(背景) { Bitmap drawBitmap =Bitmap.createBitmap(bmp.getWidth(), bmp.getHeight(), bmp.getConfig()); canvas = new Canvas(drawBitmap); paint = new Paint(); canvas.drawBitmap(bmp, 0, 0, paint); paint.setXfermode(new PorterDuffXfermode(android. graphics.PorterDuff.Mode.LIGHTEN)); //對邊框進行縮放 int w = bm.getWidth(); int h = bm.getHeight(); //縮放比 如果圖片尺寸超過邊框尺寸 會自動匹配 float scaleX = bmp.getWidth()*1F / w; float scaleY = bmp.getHeight()*1F / h; Matrix matrix = new Matrix(); matrix.postScale(scaleX, scaleY); //縮放圖片 Bitmap copyBitmap = Bitmap.createBitmap(bm, 0, 0, w, h, matrix, true); canvas.drawBitmap(copyBitmap, 0, 0, paint); imageShow.setImageBitmap(drawBitmap); }
   第2種方法是參照《Android多媒體開發高級編程》,但是它圖片104合成效果不是很好:
//模式2合成圖片 showImageBn2 = (Button)findViewById(R.id.button4); showImageBn2.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { Bitmap bitmap = getImageFromAssets("image07.png"); //第2種合成方法 imageShow.setImageBitmap(addFrameToImageTwo(bitmap)); } });
    然后通過自定義函數實現:
//圖片合成 private Bitmap addFrameToImageTwo(Bitmap frameBitmap) //bmp原圖 frameBitmap資源圖片(邊框) { //bmp原圖 創建新位圖 int width = bmp.getWidth(); int height = bmp.getHeight(); Bitmap drawBitmap =Bitmap.createBitmap(width, height, Config.RGB_565); //對邊框進行縮放 int w = frameBitmap.getWidth(); int h = frameBitmap.getHeight(); float scaleX = width*1F / w; //縮放比 如果圖片尺寸超過邊框尺寸 會自動匹配 float scaleY = height*1F / h; Matrix matrix = new Matrix(); matrix.postScale(scaleX, scaleY); //縮放圖片 Bitmap copyBitmap = Bitmap.createBitmap(frameBitmap, 0, 0, w, h, matrix, true); int pixColor = 0; int layColor = 0; int newColor = 0; int pixR = 0; int pixG = 0; int pixB = 0; int pixA = 0; int newR = 0; int newG = 0; int newB = 0; int newA = 0; int layR = 0; int layG = 0; int layB = 0; int layA = 0; float alpha = 0.8F; float alphaR = 0F; float alphaG = 0F; float alphaB = 0F; for (int i = 0; i < width; i++) { for (int k = 0; k < height; k++) { pixColor = bmp.getPixel(i, k); layColor = copyBitmap.getPixel(i, k); // 獲得原圖片的RGBA值 pixR = Color.red(pixColor); pixG = Color.green(pixColor); pixB = Color.blue(pixColor); pixA = Color.alpha(pixColor); // 獲得邊框圖片的RGBA值 layR = Color.red(layColor); layG = Color.green(layColor); layB = Color.blue(layColor); layA = Color.alpha(layColor); // 色彩與純黑色相近的點 if (layR < 20 && layG < 20 && layB < 20) { alpha = 1F; } else { alpha = 0.3F; } alphaR = alpha; alphaG = alpha; alphaB = alpha; // 兩種色彩疊加 newR = (int) (pixR * alphaR + layR * (1 - alphaR)); newG = (int) (pixG * alphaG + layG * (1 - alphaG)); newB = (int) (pixB * alphaB + layB * (1 - alphaB)); layA = (int) (pixA * alpha + layA * (1 - alpha)); // 值在0~255之間 newR = Math.min(255, Math.max(0, newR)); newG = Math.min(255, Math.max(0, newG)); newB = Math.min(255, Math.max(0, newB)); newA = Math.min(255, Math.max(0, layA)); //繪制 newColor = Color.argb(newA, newR, newG, newB); drawBitmap.setPixel(i, k, newColor); } } return drawBitmap; }
   它的運行效果以下所示,其中前2附圖是方法1,但是它的合成效果不是很優秀,而第3張圖是第2種方法,但是它的響應時間略微要長些.
            
   在第1種方法通過PoterDuffXfermode類作為過渡模式,該類因Thomas Porter和Tom Duff而得名,他們于1984年在ACM SIGGRAPH計算機圖形學發表“Compositing digital images(合成數字圖象)”的文章,它介紹了彼此堆疊繪制圖象的不同規則.這些規則定義了哪些圖象的哪些部份將出現在結果輸出中.
    在Android的PorterDuff.Mode類中羅列了Porter和Duff及其他更多人制定的規則.
    android.graphics.PorterDuff.Mode.SRC:此規則意味著只繪制源圖象,當前它正是利用此規則的Paint對象.
    android.graphics.PorterDuff.Mode.DST:此規則意味著只顯示目標圖象,在已有畫布上的初始圖象.

    以下圖所示,定義Mode值以下:
                                   
    其中,有4個規則定義了當1幅圖象放置在另外一幅圖象上時如何合成這兩幅圖象,它是我們常常使用的值:
   
android.graphics.PorterDuff.Mode.LIGHTEN:取得每一個位置上兩幅圖象中最亮的像素并顯示.
    an
droid.graphics.PorterDuff.Mode.DARKEN:取得每一個位置上兩幅圖象中最暗的像素并顯示.
    an
droid.graphics.PorterDuff.Mode.MULTIPLY:將每一個位置的兩個像素相乘,除以255,使用該值創建1個新的像素進行顯示.結果色彩=頂部色彩*底部色彩/255.
    android.graphics.PorterDuff.Mode.SCREEN:反轉每一個色彩,履行相同操作.結果色彩=255-(((255-頂部色彩)*(255-底部色彩))/255)

3. 圓形和圓角矩形顯示圖片

   最后講述如何實現圓形和圓角矩形顯示圖片,在onCreate函數中添加以下代碼:
//圓角合成圖片 roundImageBn = (Button)findViewById(R.id.button5); roundImageBn.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { imageShow.setImageBitmap(getRoundedCornerBitmap(bmp) ); } });
   然后通過自定義函數getRoundedCornerBitmap實現圓形:
//生成圓角圖片 private Bitmap getRoundedCornerBitmap(Bitmap bitmap) { Bitmap roundBitmap = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), Config.ARGB_8888); Canvas canvas = new Canvas(roundBitmap); int color = 0xff424242; Paint paint = new Paint(); //設置圓形半徑 int radius; if(bitmap.getWidth()>bitmap.getHeight()) { radius = bitmap.getHeight()/2; } else { radius = bitmap.getWidth()/2; } //繪制圓形 paint.setAntiAlias(true); canvas.drawARGB(0, 0, 0, 0); paint.setColor(color); canvas.drawCircle( bitmap.getWidth()/ 2, bitmap.getHeight() / 2, radius, paint); paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN)); canvas.drawBitmap(bitmap, 0, 0, paint); return roundBitmap; }
   一樣,如果把該函數里面內容替換便可實現圓形矩形顯示圖片:
private Bitmap getRoundedCornerBitmap(Bitmap bitmap) { //繪制圓角矩形 Bitmap roundBitmap = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), Config.ARGB_8888); Canvas canvas = new Canvas(roundBitmap); int color = 0xff424242; Paint paint = new Paint(); Rect rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight()); RectF rectF = new RectF(rect); float roundPx = 80; //轉角設置80 //繪制 paint.setAntiAlias(true); canvas.drawARGB(0, 0, 0, 0); paint.setColor(color); canvas.drawRoundRect(rectF, roundPx, roundPx, paint); paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN)); canvas.drawBitmap(bitmap, rect, rect, paint); }
   運行結果以下圖所示:
                                  
    總結:
    該文章主要講述如何給圖象增加相框,圓角顯示圖象和圖象合成的介紹.里面主要通過源碼并有詳細的進程,為何要寫這篇文章?由于在圖象處理中我認為這類添加邊框、改變邊框、圖片合成都屬于同1種類型的變化和渲染.該圖象處理軟件還沒有整合,推薦大家看下面資料中兩本書.
   
最后希望文章對大家有所幫助,如果有不足或毛病的地方請見諒!不論如何,我覺得這篇文章自己寫得不錯,自己先給自己1個贊吧!加油(^o^)/~
    下載地址:http://download.csdn.net/detail/eastmount/8102845
    源碼基本格式以下圖所示:

(By:Eastmount 2014⑴0⑶1 夜3點 http://blog.csdn.net/eastmount)
參考資料與推薦博文:
1.最該感謝的是兩本書的作者《Android多媒體開發高級編程》和《Android圖片處理總結 著:jacpy.may》,網上很多資料都是它們.
2.android圖象處理系列之6--給圖片添加邊框(下)-圖片疊加 
作者-SJF0115 他是轉載了該書的1些文章,也非常不錯.

3.Android 圖片合成:添加蒙板效果 不規則相框 透明度漸變效果的實現
作者-HappyDelano 非常不錯的文章,講述了4張圖實現桃心顯示的效果.
4.Android圖片合成 作者-johnlxj 講述了圖片合成的實現進程.
5.Android 完善實現圖片圓角和圓形(對實現進行分析)
作者-鴻洋_ 該作者很多android文章都非常不錯
6.android 畫圖之setXfermode 作者-lipeng88213 推薦起鏈接的Android圖片倒影
7.Android ImageView點擊選中后添加邊框 作者-黑米粥 該方法在切換圖片中實用
8.android 輕松實現在線即時聊天【圖片、語音、表情、文字】 作者-anonymousblogs
生活不易,碼農辛苦
如果您覺得本網站對您的學習有所幫助,可以手機掃描二維碼進行捐贈
程序員人生
------分隔線----------------------------
分享到:
------分隔線----------------------------
關閉
程序員人生
主站蜘蛛池模板: 黄色网址网站在线观看 | 国产xxxxxx久色视频在 | 国产逼逼视频 | www.噜噜噜 | 高清视频在线观看 | 久久久久国产精品美女毛片 | 宅男午夜 | 最新日韩精品 | 欧美色老汉 | jizz日本老师jizz在线播放 | 加勒比一道本综合 | 亚洲图欧美 | 福利视频欧美一区二区三区 | 国产成人乱码一区二区三区 | www.男女| 色偷偷亚洲女人天堂观看欧 | 亚洲第一页国产 | 亚洲欧美成人在线 | 手机看片福利日韩国产 | 一级特黄aa大片免费 | 可以免费观看一级毛片黄a 可以免费看的黄色网址 | 性生交大片免费一级 | 国产亚洲欧美另类久久久 | 欧美日韩性猛交xxxxx免费看 | 猛性xxxxx| 最近的免费中文字幕1 | 欧美三级午夜伦理片 | 国产欧美在线观看不卡一 | 最近中文字幕国语免费 | 最近最新视频中文字幕4 | 国产精品亚洲片夜色在线 | 国产在线观看一区二区三区 | 日韩欧美一级a毛片欧美一级 | 3344成年站福利在线视频免费 | 一区二区三区在线免费 | 一牛精品视频在线观看免费 | 在线久综合色手机在线播放 | 成年人性生活免费视频 | 亚洲天堂一区二区三区 | 91 视频网站| 日本视频一区二区三区 |