[Android] 给图像加入相框、圆形圆角显示图片、图像合成知识
生活随笔
收集整理的這篇文章主要介紹了
[Android] 给图像加入相框、圆形圆角显示图片、图像合成知识
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
? ? 前一篇文章講述了Android觸屏setOnTouchListener實現突破縮放、移動、繪制和加入水印,繼續我的"隨手拍"項目完畢給圖片加入相框、圓形圓角顯示圖片和圖像合成的功能介紹.希望文章對大家有所幫助.
一. 打開圖片和顯示assets文件里圖片
? ? 首先,對XML中activity_main.xml進行布局,通過使用RelativeLayout相對布局完畢(XML代碼后面附).然后,在Mainctivity.java中public class MainActivity extends Activity函數加入代碼例如以下,加入點擊button監聽事件:
//控件 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() {@Overridepublic 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 { //加載圖片尺寸大小沒加載圖片本身 trueBitmapFactory.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; } } //圖像真正解碼 falsebmpFactoryOptions.inJustDecodeBounds = false; bmp = BitmapFactory.decodeStream(getContentResolver().openInputStream(imageFileUri), null, bmpFactoryOptions); imageShow.setImageBitmap(bmp);}catch(FileNotFoundException e) { e.printStackTrace(); } } //end if }
? ? 上面點擊"打開"button能實現打開圖片,而在講述為圖片加入邊框時,它事實上就是通過兩張或多張圖片的合成實現的.
? ? 在jacpy.may《Android圖片處理總結》文檔中建議圖片不要放在drawable文件夾下,由于屏幕分辨率會影響圖片的大小.最好放在assets文件夾里,它代表應用無法直接訪問的原生資源(通常載入PNG透明圖實現邊框合成),僅僅能以流的方式讀取而且小于1M.
? ? 讀取assets文件夾中圖片的方法例如以下,首先手動加入PNG圖片至assets文件夾,然后在omCreate函數中加入例如以下代碼:
//顯示assets中圖片 showImageBn = (Button)findViewById(R.id.button2); showImageBn.setOnClickListener(new OnClickListener() {@Overridepublic 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" ><!-- 底部加入按鈕 --><RelativeLayoutandroid: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" ><Buttonandroid:id="@+id/button1"android:layout_width="wrap_content"android:layout_height="match_parent"android:layout_weight="1"android:text="打開" /><Buttonandroid:id="@+id/button2"android:layout_width="wrap_content"android:layout_height="match_parent"android:layout_weight="1"android:text="顯示" /><Buttonandroid:id="@+id/button3"android:layout_width="wrap_content"android:layout_height="match_parent"android:layout_weight="1"android:text="邊框" /><Buttonandroid:id="@+id/button4"android:layout_width="wrap_content"android:layout_height="match_parent"android:layout_weight="1"android:text="桃心" /><Buttonandroid:id="@+id/button5"android:layout_width="wrap_content"android:layout_height="match_parent"android:layout_weight="1"android:text="圓形" /></LinearLayout></RelativeLayout><!-- 頂部顯示圖片 --><RelativeLayoutandroid: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"><ImageViewandroid:id="@+id/imageView1"android:layout_width="fill_parent"android:layout_height="fill_parent"android:layout_gravity="center_horizontal" /></RelativeLayout> </RelativeLayout>
二. 加入相框與圖片合成
? ? 然后開始完畢圖片合成的工作,這里我採用兩種方法完畢.繼續在onCreate函數中加入代碼: //模式1合成圖片 showImageBn1 = (Button)findViewById(R.id.button3); showImageBn1.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {Bitmap bitmap = getImageFromAssets("image01.png");addFrameToImage(bitmap);} });? ?通過自己定義函數addFrameToImage實現載入圖片合成.首先創建一個空的可變為圖對象,它的大小和配置與打開的圖像同樣,隨后構建一個Canvas對象和一個Paint對象,在畫布上繪制第一個位圖對象,它成為了合成操作的目標.? ? 如今設置Paint對象上的過渡模式,通過傳入一個定義操作模式的常量,實例化一個新的PorterDuffXfermode對象.然后在Canvas對象上繪制第二個位圖對象,并將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); }? ?另外一種方法是參照《Android多媒體開發高級編程》,可是它圖片十四合成效果不是非常好: //模式2合成圖片 showImageBn2 = (Button)findViewById(R.id.button4); showImageBn2.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {Bitmap bitmap = getImageFromAssets("image07.png");//另外一種合成方法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附圖是方法一,可是它的合成效果不是非常優秀,而第三張圖是另外一種方法,可是它的響應時間略微要長些.
? ? ??? ? ?? ? ?在第一種方法通過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個規則定義了當一幅圖像放置在還有一幅圖像上時怎樣合成這兩幅圖像,它是我們常常使用的值:
? ? android.graphics.PorterDuff.Mode.LIGHTEN:獲得每一個位置上兩幅圖像中最亮的像素并顯示.
? ? android.graphics.PorterDuff.Mode.DARKEN:獲得每一個位置上兩幅圖像中最暗的像素并顯示.
? ? android.graphics.PorterDuff.Mode.MULTIPLY:將每一個位置的兩個像素相乘,除以255,使用該值創建一個新的像素進行顯示.結果顏色=頂部顏色*底部顏色/255.
? ? android.graphics.PorterDuff.Mode.SCREEN:反轉每一個顏色,運行同樣操作.結果顏色=255-(((255-頂部顏色)*(255-底部顏色))/255)
三. 圓形和圓角矩形顯示圖片
? ?最后講述怎樣實現圓形和圓角矩形顯示圖片,在onCreate函數中加入例如以下代碼://圓角合成圖片 roundImageBn = (Button)findViewById(R.id.button5); roundImageBn.setOnClickListener(new OnClickListener() {@Overridepublic 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); }? ?執行結果例如以下圖所看到的:
? ? ? ? ? ? ? ? ? ? ??? ? ? ? ? ?? ? ? 總結:
? ? 該文章主要講述怎樣給圖像添加相框,圓角顯示圖像和圖像合成的介紹.里面主要通過源代碼并有具體的過程,為什么要寫這篇文章?由于在圖像處理中我覺得這樣的加入邊框、改變邊框、圖片合成都屬于同一種類型的變化和渲染.該圖像處理軟件還沒有整合,推薦大家看以下資料中兩本書.
??? 最后希望文章對大家有所幫助,假設有不足或錯誤的地方請見諒。不論怎樣,我認為這篇文章自己寫得不錯,自己先給自己一個贊吧!
加油\(^o^)/~
??? 源代碼基本格式例如以下圖所看到的:
(By:Eastmount 2014-10-31 夜3點?http://blog.csdn.net/eastmount)
參考資料與推薦博文: 1.最該感謝的是兩本書的作者《Android多媒體開發高級編程》和《Android圖片處理總結 著:jacpy.may》,網上非常多資料都是它們.
2.android圖像處理系列之六--給圖片加入邊框(下)-圖片疊加?
作者-SJF0115 他是轉載了該書的一些文章,也很不錯.
3.Android 圖片合成:加入蒙板效果 不規則相框 透明度漸變效果的實現
作者-HappyDelano 很不錯的文章,講述了4張圖實現桃心顯示的效果.
4.Android圖片合成?作者-johnlxj 講述了圖片合成的實現過程.
5.Android 完美實現圖片圓角和圓形(對實現進行分析)
作者-鴻洋_ 該作者非常多android文章都非常不錯
6.android 繪圖之setXfermode?作者-lipeng88213 推薦起鏈接的Android圖片倒影
7.Android ImageView點擊選中后加入邊框?作者-黑米粥 該方法在切換圖片中有用
8.android 輕松實如今線即時聊天【圖片、語音、表情、文字】?作者-anonymousblogs
總結
以上是生活随笔為你收集整理的[Android] 给图像加入相框、圆形圆角显示图片、图像合成知识的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: JNI编程基础(二)——Android
- 下一篇: @ConfigurationProper