因为随手拍项目想做成类似于美图秀秀那种底部有一排Menu实现不同效果的功能,这里先简介怎样通过Menu实现打开相冊中的图片、怀旧效果、浮雕效果、光照效果和素描效果.后面可能会讲述怎样通过PopupWindow实现自己定义的Menu效果.

    希望文章对大家有所帮助,假设有错误或不足之处请海涵~

一. Menu效果展示

   Android手机上有个Menu按键,点击他会弹出一个菜单,通常在屏幕底部或右上角,在选项菜单OptionsMenu中最多显示2排每排3个菜单项,能够包括自己定义的图片和文字.假设Menu菜单项多于6项时,第6项(Expanded Menus,扩展菜单)会变成More,点击它会显示后面所隐藏的全部选项.

    以下讲述怎样在Android 4.0项目中实现简单的Menu功能.加入例如以下代码:
  1. @Override
  2. public boolean onCreateOptionsMenu(Menu menu) { //创建Menu
  3. //自己定义menu 加入图标(使用自带图标)
  4. menu.add(Menu.NONE, Menu.FIRST + 1 , 1, "打开").
  5. setIcon(android.R.drawable.ic_menu_slideshow);
  6. menu.add(Menu.NONE, Menu.FIRST + 2 , 2, "怀旧").
  7. setIcon(android.R.drawable.ic_menu_edit);
  8. menu.add(Menu.NONE, Menu.FIRST + 3 , 3, "浮雕").
  9. setIcon(android.R.drawable.ic_menu_gallery);
  10. menu.add(Menu.NONE, Menu.FIRST + 4 , 4, "模糊").
  11. setIcon(android.R.drawable.ic_menu_crop);
  12. menu.add(Menu.NONE, Menu.FIRST + 5 , 5, "光照").
  13. setIcon(android.R.drawable.ic_menu_camera);
  14. menu.add(Menu.NONE, Menu.FIRST + 6 , 6, "锐化").
  15. setIcon(android.R.drawable.ic_menu_view);
  16. return true;
  17. }

   因为Android 4.0系统缺省UI风格有所变化,所以须要设置Activity的theme为Theme.Light.同一时候也能够在res/menu/main.xml设置菜单项.參考"恺风"博主关于Menu的介绍,很不错.http://blog.csdn.net/flowingflying/article/details/11967301

  1. <activity
  2. android:name="com.example.menushowimage.MainActivity"
  3. android:label="@string/app_name"
  4. android:theme="@android:style/Theme.Light" >

   下图是设置前面的显示Menu不同效果,同一时候我调用的图标都是Android自带的图片,用户也能够自己定义.(

url=tt6IgAjYh9ylTNsbYPTslH-sBz0vYfncK4MwssMOGJfzx0NBbjGvL_4PSK5wtAsxXKj5aw5Z05VM3yrtWp-TbkzVjnHa28oGjiDe2K1Soda">android默认图标列表)

                                       

   
同一时候设置XML格式显示图片:

  1. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
  2. xmlns:tools="http://schemas.android.com/tools"
  3. android:id="@+id/container"
  4. android:layout_width="match_parent"
  5. android:layout_height="match_parent"
  6. tools:context="com.example.touchimagetest.MainActivity"
  7. tools:ignore="MergeRootFrame" >
  8. <!-- 顶部加入文字 -->
  9. <RelativeLayout
  10. android:id="@+id/Layout_top"
  11. android:orientation="horizontal"
  12. android:layout_width="fill_parent"
  13. android:layout_height="25dp"
  14. android:layout_alignParentTop="true"
  15. android:gravity="center">
  16. <TextView
  17. android:id="@+id/textView1"
  18. android:layout_width="wrap_content"
  19. android:layout_height="wrap_content"
  20. android:textSize="20sp"
  21. android:text="请点击menu处理图片" />
  22. </RelativeLayout>
  23. <!-- 底部显示图片 -->
  24. <RelativeLayout
  25. android:id="@+id/Layout_bottom"
  26. android:orientation="horizontal"
  27. android:layout_below="@id/Layout_top"
  28. android:layout_width="fill_parent"
  29. android:layout_height="wrap_content"
  30. android:background="#EFDFDF"
  31. android:gravity="center">
  32. <ImageView
  33. android:id="@+id/imageView1"
  34. android:layout_width="fill_parent"
  35. android:layout_height="fill_parent"
  36. android:layout_gravity="center_horizontal" />
  37. </RelativeLayout>
  38. </RelativeLayout>

二. Menu实现打开图片

   然后通过onOptionsItemSelected(MenuItem item)实现选择图片,通过调用自己定义函数实现各种功能.
  1. @Override
  2. public boolean onOptionsItemSelected(MenuItem item) { //选择Menu
  3. //选择id 相应Menu.add的參数Menu.FIRST+i
  4. int id = item.getItemId();
  5. switch(id) {
  6. case Menu.FIRST+1:
  7. Toast.makeText(this, "打开图片", Toast.LENGTH_SHORT).show();
  8. OpenImage();
  9. break;
  10. case Menu.FIRST+2:
  11. Toast.makeText(this, "图片怀旧效果", Toast.LENGTH_SHORT).show();
  12. OldRemeberImage();
  13. break;
  14. case Menu.FIRST+3:
  15. Toast.makeText(this, "图片浮雕效果", Toast.LENGTH_SHORT).show();
  16. ReliefImage();
  17. break;
  18. case Menu.FIRST+4:
  19. Toast.makeText(this, "图片模糊效果", Toast.LENGTH_SHORT).show();
  20. FuzzyImage();
  21. break;
  22. case Menu.FIRST+5:
  23. Toast.makeText(this, "图片光照效果", Toast.LENGTH_SHORT).show();
  24. SunshineImage();
  25. break;
  26. case Menu.FIRST+6:
  27. Toast.makeText(this, "图片锐化效果", Toast.LENGTH_SHORT).show();
  28. SharpenImage();
  29. break;
  30. }
  31.  
  32. return super.onOptionsItemSelected(item);
  33. }

   当中打开图片函数实现方法例如以下,而上面的非常多自己定义函数都将在第三部分介绍,你此处能够凝视掉仅仅验证"打开图片".首先加入自己定义变量和获取ImageView布局.

  1. //自己定义变量
  2. private ImageView imageShow; //显示图片
  3. private Bitmap bmp; //原始图片
  4. private final int IMAGE_OPEN = 0; //打开图片
  5. @Override
  6. protected void onCreate(Bundle savedInstanceState) {
  7. super.onCreate(savedInstanceState);
  8. setContentView(R.layout.activity_main);
  9. imageShow = (ImageView) findViewById(R.id.imageView1);
  10. if (savedInstanceState == null) {
  11. getFragmentManager().beginTransaction()
  12. .add(R.id.container, new PlaceholderFragment())
  13. .commit();
  14. }
  15. }
   
然后通过自己定义函数OpenImage打开函数,与前面文章介绍的方法一样.

  1. //自己定义函数 打开图片
  2. public void OpenImage()
  3. {
  4. Intent intent = new Intent(Intent.ACTION_PICK,
  5. android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
  6. startActivityForResult(intent, IMAGE_OPEN);
  7. }
  8. //显示打开图片
  9. protected void onActivityResult(int requestCode, int resultCode, Intent data) {
  10. super.onActivityResult(requestCode, resultCode, data);
  11. if(resultCode==RESULT_OK && requestCode==IMAGE_OPEN) {
  12. Uri imageFileUri = data.getData();
  13. DisplayMetrics dm = new DisplayMetrics();
  14. getWindowManager().getDefaultDisplay().getMetrics(dm);
  15. int width = dm.widthPixels; //手机屏幕水平分辨率
  16. int height = dm.heightPixels; //手机屏幕垂直分辨率
  17. try {
  18. //加载图片尺寸大小没加载图片本身 true
  19. BitmapFactory.Options bmpFactoryOptions = new BitmapFactory.Options();
  20. bmpFactoryOptions.inJustDecodeBounds = true;
  21. bmp = BitmapFactory.decodeStream(getContentResolver().openInputStream(imageFileUri), null, bmpFactoryOptions);
  22. int heightRatio = (int)Math.ceil(bmpFactoryOptions.outHeight/(float)height);
  23. int widthRatio = (int)Math.ceil(bmpFactoryOptions.outWidth/(float)width);
  24. //inSampleSize表示图片占原图比例 1表示原图
  25. if(heightRatio>1&&widthRatio>1) {
  26. if(heightRatio>widthRatio) {
  27. bmpFactoryOptions.inSampleSize = heightRatio;
  28. }
  29. else {
  30. bmpFactoryOptions.inSampleSize = widthRatio;
  31. }
  32. }
  33. //图像真正解码 false
  34. bmpFactoryOptions.inJustDecodeBounds = false;
  35. bmp = BitmapFactory.decodeStream(getContentResolver().openInputStream(imageFileUri), null, bmpFactoryOptions);
  36. imageShow.setImageBitmap(bmp);
  37. }
  38. catch(FileNotFoundException e) {
  39. e.printStackTrace();
  40. }
  41. } //end if
  42. }
    以下讲讲使用Options Menu的函数:

   onCreateOptionsMenu(Menu
menu)创建options
menu,这个函数仅仅会在menu第一次显示时调用.

    onOptionsItemSelected(MenuItem
item)处理选中的菜单项.

    在通过menu.add函数实现加入菜单项,如menu.add(Menu.NONE,Menu.FIRST+1,1,"打开"),第一个參数表示组别;第二个參数menu标志编号与onOptionsItemSelected函数中值相应;第三个參数是在菜单中出现的顺序,顺序由小到大,由左至右;第四个參数是显示的文字,同一时候setIcon能够设置图标.

三. 图像各种效果实现

   
最后讲讲各个效果实现过程,通过不同自己定义函数实现.当中各个效果主要參照《Android图像处理总结》那篇文章和eoeAndroid社区亚瑟的文章.

    书籍下载地址:

1.图片怀旧效果
  1. //图片怀旧处理
  2. private void OldRemeberImage()
  3. {
  4. /*
  5. * 怀旧处理算法即设置新的RGB
  6. * R=0.393r+0.769g+0.189b
  7. * G=0.349r+0.686g+0.168b
  8. * B=0.272r+0.534g+0.131b
  9. */
  10. int width = bmp.getWidth();
  11. int height = bmp.getHeight();
  12. Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565);
  13. int pixColor = 0;
  14. int pixR = 0;
  15. int pixG = 0;
  16. int pixB = 0;
  17. int newR = 0;
  18. int newG = 0;
  19. int newB = 0;
  20. int[] pixels = new int[width * height];
  21. bmp.getPixels(pixels, 0, width, 0, 0, width, height);
  22. for (int i = 0; i < height; i++)
  23. {
  24. for (int k = 0; k < width; k++)
  25. {
  26. pixColor = pixels[width * i + k];
  27. pixR = Color.red(pixColor);
  28. pixG = Color.green(pixColor);
  29. pixB = Color.blue(pixColor);
  30. newR = (int) (0.393 * pixR + 0.769 * pixG + 0.189 * pixB);
  31. newG = (int) (0.349 * pixR + 0.686 * pixG + 0.168 * pixB);
  32. newB = (int) (0.272 * pixR + 0.534 * pixG + 0.131 * pixB);
  33. int newColor = Color.argb(255, newR > 255 ?
  34.  
  35. 255 : newR, newG > 255 ? 255 : newG, newB > 255 ? 255 : newB);
  36. pixels[width * i + k] = newColor;
  37. }
  38. }
  39. bitmap.setPixels(pixels, 0, width, 0, 0, width, height);
  40. imageShow.setImageBitmap(bitmap);
  41. }

    显示效果例如以下图所看到的:

                     

2.图片浮雕效果
  1. //图片浮雕处理
  2. //底片效果也很easy:将当前像素点的RGB值分别与255之差后的值作为当前点的RGB
  3. //灰度图像:通常使用的方法是gray=0.3*pixR+0.59*pixG+0.11*pixB
  4. private void ReliefImage()
  5. {
  6. /*
  7. * 算法原理:(前一个像素点RGB-当前像素点RGB+127)作为当前像素点RGB值
  8. * 在ABC中计算B点浮雕效果(RGB值在0~255)
  9. * B.r = C.r - B.r + 127
  10. * B.g = C.g - B.g + 127
  11. * B.b = C.b - B.b + 127
  12. */
  13. int width = bmp.getWidth();
  14. int height = bmp.getHeight();
  15. Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565);
  16. int pixColor = 0;
  17. int pixR = 0;
  18. int pixG = 0;
  19. int pixB = 0;
  20. int newR = 0;
  21. int newG = 0;
  22. int newB = 0;
  23. int[] pixels = new int[width * height];
  24. bmp.getPixels(pixels, 0, width, 0, 0, width, height);
  25. for (int i = 1; i < height-1; i++)
  26. {
  27. for (int k = 1; k < width-1; k++)
  28. {
  29. //获取前一个像素颜色
  30. pixColor = pixels[width * i + k];
  31. pixR = Color.red(pixColor);
  32. pixG = Color.green(pixColor);
  33. pixB = Color.blue(pixColor);
  34. //获取当前像素
  35. pixColor = pixels[(width * i + k) + 1];
  36. newR = Color.red(pixColor) - pixR +127;
  37. newG = Color.green(pixColor) - pixG +127;
  38. newB = Color.blue(pixColor) - pixB +127;
  39. newR = Math.min(255, Math.max(0, newR));
  40. newG = Math.min(255, Math.max(0, newG));
  41. newB = Math.min(255, Math.max(0, newB));
  42. pixels[width * i + k] = Color.argb(255, newR, newG, newB);
  43. }
  44. }
  45. bitmap.setPixels(pixels, 0, width, 0, 0, width, height);
  46. imageShow.setImageBitmap(bitmap);
  47. }

   显示效果例如以下图所看到的:

                       

3.图像模糊效果

  1. //图像模糊处理
  2. private void FuzzyImage()
  3. {
  4. /*
  5. * 算法原理:
  6. * 简单算法将像素周围八个点包含自身共九个点RGB值分别相加后平均,当前像素点的RGB值
  7. * 复杂算法採用高斯模糊
  8. * 高斯矩阵 int[] gauss = new int[] { 1, 2, 1, 2, 4, 2, 1, 2, 1 };
  9. * 将九个点的RGB值分别与高斯矩阵中的相应项相乘的和,再除以一个相应的值作为当前像素点的RGB
  10. */
  11. int[] gauss = new int[] { 1, 2, 1, 2, 4, 2, 1, 2, 1 }; // 高斯矩阵
  12. int delta = 16; // 除以值 值越小图片会越亮,越大则越暗
  13. int width = bmp.getWidth();
  14. int height = bmp.getHeight();
  15. Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565);
  16. int pixColor = 0;
  17. int pixR = 0;
  18. int pixG = 0;
  19. int pixB = 0;
  20. int newR, newG, newB;
  21. int pos = 0; //位置
  22. int[] pixels = new int[width * height];
  23. bmp.getPixels(pixels, 0, width, 0, 0, width, height);
  24. //循环赋值
  25. for (int i = 1; i < height-1; i++)
  26. {
  27. for (int k = 1; k < width-1; k++)
  28. {
  29. pos = 0;
  30. newR = 0;
  31. newG = 0;
  32. newB = 0;
  33. for (int m = -1; m <= 1; m++) //宽不变
  34. {
  35. for (int n = -1; n <= 1; n++) //高先变
  36. {
  37. pixColor = pixels[(i + m) * width + k + n];
  38. pixR = Color.red(pixColor);
  39. pixG = Color.green(pixColor);
  40. pixB = Color.blue(pixColor);
  41. //3*3像素相加
  42. newR = newR + (int) (pixR * gauss[pos]);
  43. newG = newG + (int) (pixG * gauss[pos]);
  44. newB = newB + (int) (pixB * gauss[pos]);
  45. pos++;
  46. }
  47. }
  48. newR /= delta;
  49. newG /= delta;
  50. newB /= delta;
  51. newR = Math.min(255, Math.max(0, newR));
  52. newG = Math.min(255, Math.max(0, newG));
  53. newB = Math.min(255, Math.max(0, newB));
  54. pixels[i * width + k] = Color.argb(255, newR, newG, newB);
  55. }
  56. }
  57. bitmap.setPixels(pixels, 0, width, 0, 0, width, height);
  58. imageShow.setImageBitmap(bitmap);
  59. }
   
该图显示效果不是非常理想,对高斯模糊理解还不够,建议大家看我收藏合集里面讲述模糊的超链接.

4.图像光照效果

  1. //图片光照效果
  2. private void SunshineImage()
  3. {
  4. /*
  5. * 算法原理:(前一个像素点RGB-当前像素点RGB+127)作为当前像素点RGB值
  6. * 在ABC中计算B点浮雕效果(RGB值在0~255)
  7. * B.r = C.r - B.r + 127
  8. * B.g = C.g - B.g + 127
  9. * B.b = C.b - B.b + 127
  10. * 光照中心取长宽较小值为半径,也能够自己定义从左上角射过来
  11. */
  12. int width = bmp.getWidth();
  13. int height = bmp.getHeight();
  14. Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565);
  15. int pixColor = 0;
  16. int pixR = 0;
  17. int pixG = 0;
  18. int pixB = 0;
  19. int newR = 0;
  20. int newG = 0;
  21. int newB = 0;
  22. //环绕圆形光照
  23. int centerX = width / 2;
  24. int centerY = height / 2;
  25. int radius = Math.min(centerX, centerY);
  26. float strength = 150F; //光照强度100-150
  27. int[] pixels = new int[width * height];
  28. bmp.getPixels(pixels, 0, width, 0, 0, width, height);
  29. for (int i = 1; i < height-1; i++)
  30. {
  31. for (int k = 1; k < width-1; k++)
  32. {
  33. //获取前一个像素颜色
  34. pixColor = pixels[width * i + k];
  35. pixR = Color.red(pixColor);
  36. pixG = Color.green(pixColor);
  37. pixB = Color.blue(pixColor);
  38. newR = pixR;
  39. newG = pixG;
  40. newB = pixB;
  41. //计算当前点到光照中心的距离,平面坐标系中两点之间的距离
  42. int distance = (int) (Math.pow((centerY-i), 2) + Math.pow((centerX-k), 2));
  43. if(distance < radius*radius)
  44. {
  45. //依照距离大小计算增强的光照值
  46. int result = (int)(strength*( 1.0-Math.sqrt(distance) / radius ));
  47. newR = pixR + result;
  48. newG = newG + result;
  49. newB = pixB + result;
  50. }
  51. newR = Math.min(255, Math.max(0, newR));
  52. newG = Math.min(255, Math.max(0, newG));
  53. newB = Math.min(255, Math.max(0, newB));
  54. pixels[width * i + k] = Color.argb(255, newR, newG, newB);
  55. }
  56. }
  57. bitmap.setPixels(pixels, 0, width, 0, 0, width, height);
  58. imageShow.setImageBitmap(bitmap);
  59. }

    显示效果例如以下图所看到的 

                                                          

5.图片锐化效果

    本打算採用拉普拉斯算子或Sobel算子对图像进行锐化,在使用C++对24位bmp图像处理时能非常好的显示图像的轮廓,可是Android总是效果不是非常好啊,并且有虚线!网上一些锐化效果全然没有实现显示图像轮廓,与原图差别不大,感觉是错误的方法.研究ing

  1. //图像锐化处理 拉普拉斯算子处理
  2. private void SharpenImage()
  3. {
  4. /*
  5. * 锐化基本思想是加强图像中景物的边缘和轮廓,使图像变得清晰
  6. * 而图像平滑是使图像中边界和轮廓变得模糊
  7. *
  8. * 拉普拉斯算子图像锐化
  9. * 获取周围9个点的矩阵乘以模板9个的矩阵 卷积
  10. */
  11. //拉普拉斯算子模板 { 0, -1, 0, -1, -5, -1, 0, -1, 0 } { -1, -1, -1, -1, 9, -1, -1, -1, -1 }
  12. int[] laplacian = new int[] { -1, -1, -1, -1, 9, -1, -1, -1, -1 };
  13. int width = bmp.getWidth();
  14. int height = bmp.getHeight();
  15. Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565);
  16. int pixR = 0;
  17. int pixG = 0;
  18. int pixB = 0;
  19. int pixColor = 0;
  20. int newR = 0;
  21. int newG = 0;
  22. int newB = 0;
  23. int idx = 0;
  24. float alpha = 0.3F; //图片透明度
  25. int[] pixels = new int[width * height];
  26. bmp.getPixels(pixels, 0, width, 0, 0, width, height);
  27. //图像处理
  28. for (int i = 1; i < height - 1; i++)
  29. {
  30. for (int k = 1; k < width - 1; k++)
  31. {
  32. idx = 0;
  33. newR = 0;
  34. newG = 0;
  35. newB = 0;
  36. for (int n = -1; n <= 1; n++) //取出图像3*3领域像素
  37. {
  38. for (int m = -1; m <= 1; m++) //n行数不变 m列变换
  39. {
  40. pixColor = pixels[(i + n) * width + k + m]; //当前点(i,k)
  41. pixR = Color.red(pixColor);
  42. pixG = Color.green(pixColor);
  43. pixB = Color.blue(pixColor);
  44. //图像像素与相应摸板相乘
  45. newR = newR + (int) (pixR * laplacian[idx] * alpha);
  46. newG = newG + (int) (pixG * laplacian[idx] * alpha);
  47. newB = newB + (int) (pixB * laplacian[idx] * alpha);
  48. idx++;
  49. }
  50. }
  51. newR = Math.min(255, Math.max(0, newR));
  52. newG = Math.min(255, Math.max(0, newG));
  53. newB = Math.min(255, Math.max(0, newB));
  54. //赋值
  55. pixels[i * width + k] = Color.argb(255, newR, newG, newB);
  56. }
  57. }
  58. bitmap.setPixels(pixels, 0, width, 0, 0, width, height);
  59. imageShow.setImageBitmap(bitmap);
  60. }

   作图是其显示效果,而右图是我曾经《数字图像处理》课用C++写的不同模版的锐化效果.

           

    以下再介绍些效果,以下这个效果是參考亚瑟BOY的冰冻效果.

    源码地址:http://www.eoeandroid.com/thread-176490-1-1.html

  1. //图片冰冻效果
  2. private void IceImage()
  3. {
  4. int width = bmp.getWidth();
  5. int height = bmp.getHeight();
  6. Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565);
  7. int pixColor = 0;
  8. int pixR = 0;
  9. int pixG = 0;
  10. int pixB = 0;
  11. int newColor = 0;
  12. int newR = 0;
  13. int newG = 0;
  14. int newB =0;
  15. int[] pixels = new int[width * height];
  16. bmp.getPixels(pixels, 0, width, 0, 0, width, height);
  17. for (int i = 0; i < height; i++)
  18. {
  19. for (int k = 0; k < width; k++)
  20. {
  21. //获取前一个像素颜色
  22. pixColor = pixels[width * i + k];
  23. pixR = Color.red(pixColor);
  24. pixG = Color.green(pixColor);
  25. pixB = Color.blue(pixColor);
  26. //红色
  27. newColor = pixR - pixG - pixB;
  28. newColor = newColor * 3 / 2;
  29. if(newColor < 0) {
  30. newColor = -newColor;
  31. }
  32. if(newColor >255) {
  33. newColor = 255;
  34. }
  35. newR = newColor;
  36. //绿色
  37. newColor = pixG - pixB - pixR;
  38. newColor = newColor * 3 / 2;
  39. if(newColor < 0) {
  40. newColor = -newColor;
  41. }
  42. if(newColor >255) {
  43. newColor = 255;
  44. }
  45. newG = newColor;
  46. //蓝色
  47. newColor = pixB - pixG - pixR;
  48. newColor = newColor * 3 / 2;
  49. if(newColor < 0) {
  50. newColor = -newColor;
  51. }
  52. if(newColor >255) {
  53. newColor = 255;
  54. }
  55. newB = newColor;
  56. pixels[width * i + k] = Color.argb(255, newR, newG, newB);
  57. }
  58. }
  59. bitmap.setPixels(pixels, 0, width, 0, 0, width, height);
  60. imageShow.setImageBitmap(bitmap);
  61. }

 
  以下这个代码是CSDN的xu_fu博主的素描处理,对我软件实用.

    源码地址:http://blog.csdn.net/xu_fu/article/details/21485461


      效果显演示样例如以下图所看到的,在Menu选择中调用函数IceImage或SuMiaoImage就可以实现.

                      

  1. //素描效果
  2. private void SuMiaoImage()
  3. {
  4. //创建新Bitmap
  5. int width = bmp.getWidth();
  6. int height = bmp.getHeight();
  7. int[] pixels = new int[width * height]; //存储变换图像
  8. int[] linpix = new int[width * height]; //存储灰度图像
  9. Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565);
  10. bmp.getPixels(pixels, 0, width, 0, 0, width, height);
  11. int pixColor = 0;
  12. int pixR = 0;
  13. int pixG = 0;
  14. int pixB = 0;
  15. int newR = 0;
  16. int newG = 0;
  17. int newB = 0;
  18. //灰度图像
  19. for (int i = 1; i < width - 1; i++)
  20. {
  21. for (int j = 1; j < height - 1; j++) //拉普拉斯算子模板 { 0, -1, 0, -1, -5, -1, 0, -1, 0
  22. {
  23. //获取前一个像素颜色
  24. pixColor = pixels[width * i + j];
  25. pixR = Color.red(pixColor);
  26. pixG = Color.green(pixColor);
  27. pixB = Color.blue(pixColor);
  28. //灰度图像
  29. int gray=(int)(0.3*pixR+0.59*pixG+0.11*pixB);
  30. linpix[width * i + j] = Color.argb(255, gray, gray, gray);
  31. //图像反向
  32. gray=255-gray;
  33. pixels[width * i + j] = Color.argb(255, gray, gray, gray);
  34. }
  35. }
  36. int radius = Math.min(width/2, height/2);
  37. int[] copixels = gaussBlur(pixels, width, height, 10, 10/3); //高斯模糊 採用半径10
  38. int[] result = colorDodge(linpix, copixels); //素描图像 颜色减淡
  39. bitmap.setPixels(result, 0, width, 0, 0, width, height);
  40. imageShow.setImageBitmap(bitmap);
  41. }
  42.  
  43. //高斯模糊
  44. public static int[] gaussBlur(int[] data, int width, int height, int radius,
  45. float sigma) {
  46.  
  47. float pa = (float) (1 / (Math.sqrt(2 * Math.PI) * sigma));
  48. float pb = -1.0f / (2 * sigma * sigma);
  49.  
  50. // generate the Gauss Matrix
  51. float[] gaussMatrix = new float[radius * 2 + 1];
  52. float gaussSum = 0f;
  53. for (int i = 0, x = -radius; x <= radius; ++x, ++i) {
  54. float g = (float) (pa * Math.exp(pb * x * x));
  55. gaussMatrix[i] = g;
  56. gaussSum += g;
  57. }
  58.  
  59. for (int i = 0, length = gaussMatrix.length; i < length; ++i) {
  60. gaussMatrix[i] /= gaussSum;
  61. }
  62.  
  63. // x direction
  64. for (int y = 0; y < height; ++y) {
  65. for (int x = 0; x < width; ++x) {
  66. float r = 0, g = 0, b = 0;
  67. gaussSum = 0;
  68. for (int j = -radius; j <= radius; ++j) {
  69. int k = x + j;
  70. if (k >= 0 && k < width) {
  71. int index = y * width + k;
  72. int color = data[index];
  73. int cr = (color & 0x00ff0000) >> 16;
  74. int cg = (color & 0x0000ff00) >> 8;
  75. int cb = (color & 0x000000ff);
  76.  
  77. r += cr * gaussMatrix[j + radius];
  78. g += cg * gaussMatrix[j + radius];
  79. b += cb * gaussMatrix[j + radius];
  80.  
  81. gaussSum += gaussMatrix[j + radius];
  82. }
  83. }
  84.  
  85. int index = y * width + x;
  86. int cr = (int) (r / gaussSum);
  87. int cg = (int) (g / gaussSum);
  88. int cb = (int) (b / gaussSum);
  89.  
  90. data[index] = cr << 16 | cg << 8 | cb | 0xff000000;
  91. }
  92. }
  93.  
  94. // y direction
  95. for (int x = 0; x < width; ++x) {
  96. for (int y = 0; y < height; ++y) {
  97. float r = 0, g = 0, b = 0;
  98. gaussSum = 0;
  99. for (int j = -radius; j <= radius; ++j) {
  100. int k = y + j;
  101. if (k >= 0 && k < height) {
  102. int index = k * width + x;
  103. int color = data[index];
  104. int cr = (color & 0x00ff0000) >> 16;
  105. int cg = (color & 0x0000ff00) >> 8;
  106. int cb = (color & 0x000000ff);
  107.  
  108. r += cr * gaussMatrix[j + radius];
  109. g += cg * gaussMatrix[j + radius];
  110. b += cb * gaussMatrix[j + radius];
  111.  
  112. gaussSum += gaussMatrix[j + radius];
  113. }
  114. }
  115.  
  116. int index = y * width + x;
  117. int cr = (int) (r / gaussSum);
  118. int cg = (int) (g / gaussSum);
  119. int cb = (int) (b / gaussSum);
  120. data[index] = cr << 16 | cg << 8 | cb | 0xff000000;
  121. }
  122. }
  123.  
  124. return data;
  125. }
  126.  
  127. //颜色减淡
  128. public static int[] colorDodge(int[] baseColor, int[] mixColor) {
  129.  
  130. for (int i = 0, length = baseColor.length; i < length; ++i) {
  131. int bColor = baseColor[i];
  132. int br = (bColor & 0x00ff0000) >> 16;
  133. int bg = (bColor & 0x0000ff00) >> 8;
  134. int bb = (bColor & 0x000000ff);
  135.  
  136. int mColor = mixColor[i];
  137. int mr = (mColor & 0x00ff0000) >> 16;
  138. int mg = (mColor & 0x0000ff00) >> 8;
  139. int mb = (mColor & 0x000000ff);
  140.  
  141. int nr = colorDodgeFormular(br, mr);
  142. int ng = colorDodgeFormular(bg, mg);
  143. int nb = colorDodgeFormular(bb, mb);
  144.  
  145. baseColor[i] = nr << 16 | ng << 8 | nb | 0xff000000;
  146. }
  147. return baseColor;
  148. }
  149.  
  150. private static int colorDodgeFormular(int base, int mix) {
  151.  
  152. int result = base + (base * mix) / (255 - mix);
  153. result = result > 255 ?
  154.  
  155. 255 : result;
  156. return result;
  157.  
  158. }

    最后希望文章对大家有所帮助,感谢上面提到的作者,同一时候可能还有些如LOMO等效果可參考以下的文章,它是图像处理的一个集合超链接.后面会写PopupWindows实现美图秀秀的效果和对人脸进行处理.

    源码下载:

    (By:Eastmount 2014-11-2 晚8点 http://blog.csdn.net/eastmount/)

[Android] 通过Menu实现图片怀旧、浮雕、模糊、光照和素描效果的更多相关文章

  1. Android 加载大图片到内存

    本文演示android中图片加载到内存 首先设计界面: 代码如下: <LinearLayout xmlns:android="http://schemas.android.com/ap ...

  2. android 开发 - 对图片进行虚化(毛玻璃效果,模糊)

    概述 IPAD,IPHONE上首页背景的模糊效果是不是很好看,那么在 Android中如何实现呢.我通过一种方式实现了这样的效果. 开源库名称:anroid-image-blur 一个android ...

  3. Android学习笔记之图片轮播...

    PS:一个bug又折腾了一个下午....哎... 学习内容: 1.Android利用ViewPager和PagerAdapter实现图片轮播... 2.使用反射机制获取Android的资源信息... ...

  4. Android测试AsyncTask下载图片

    package com.example.myact8_async; import org.apache.http.HttpEntity; import org.apache.http.HttpResp ...

  5. Android 异步加载图片,使用LruCache和SD卡或手机缓存,效果非常的流畅

      Android 高手进阶(21)  版权声明:本文为博主原创文章,未经博主允许不得转载. 转载请注明出处http://blog.csdn.net/xiaanming/article/details ...

  6. android 开发 解码gif图片,获取每帧bitmap

    环境:android 4.3  (注意对于android4.4版本解码出来不正确,除了第一帧正确外,其余的都是显示不同的地方)  通用版本见: android 开发对gif解码(适配android 4 ...

  7. Android开源库--PhotoView图片查看

    如果说我比别人看得更远些,那是因为我站在了巨人的肩上. github地址:https://github.com/chrisbanes/PhotoView 介绍 在一般的应用中,总会遇到查看图片的功能, ...

  8. Android EditText中插入图片并响应点击事件

    EditText中插入图片基本就是两种方法: ,通过Html.fromHtml(..)来实现 [mw_shl_code=java,true]eText.append(Html.fromHtml(&qu ...

  9. Android内存中的图片

    图片在内存中的大小 Android.graphics.Bitmap类里有一个内部类Bitmap.Config类,在Bitmap类里createBitmap(intwidth, int height, ...

随机推荐

  1. 简单实现ToolStripMenuItem(菜单栏)的单选效果

    来源:http://www.97world.com/archives/2194 这几天在写又拍云的客户端,老实说确实学到了不少东西!接下来的几天我会把一些技巧或者原来没有接触过的一些东西发上来,算是复 ...

  2. VB里的TEXT控件只能输入数字的代码

    " '先声明一个常量,并把你想禁用或允许输入的内容赋值给它 Private Sub Text1_KeyPress(KeyAscii As Integer) '只能输入数字 KeyAscii ...

  3. sql server阻塞(block)处理

    sp_who2 ACTIVE --从下图可知spid = 65进程被76阻塞 --或 * FROM sys.sysprocesses WHERE blocked <> 0 ) --查看阻塞 ...

  4. jQuery中,选择器既匹配开头又匹配结尾

    jQuery中,选择器既匹配开头又匹配结尾的方法: [attr^=val]attr$=val [attr^=val][attr$=val]

  5. ylbtech-LanguageSamples-SimpleVariance

    ylbtech-Microsoft-CSharpSamples:ylbtech-LanguageSamples-SimpleVariance 1.A,示例(Sample) 返回顶部 SimpleVar ...

  6. python的FTP模块

    python本身自带一个FTP模块,可以轻松实现FTP的上传,下载等操作.下面来看看用法: from ftplib import FTP import socket    #用来设置超时时间 FTP. ...

  7. 理解Flow静态类型检查

    一.为什么在JavaScript中使用静态类型 了解静态类型的最快方法是将其与动态类型进行对比. 有静态类型参数的语言被称为静态类型语言. 另一方面,有动态类型参数的语言被称为动态类型语言.核心区别是 ...

  8. DevExpress 中 用 LookUpEdit 控件 代替 ComboBoxEdit 控件来绑定 DataTable

    绑定数据及定义列信息 LookUpEdit lue = lookUpEdit1; DataTable dt = new DataTable(); dt.Columns.Add(new DataColu ...

  9. :视频播放器与Handler 完美调用

    Handler之消息循环   Handler是用于操作线程内部的消息队列的类.这有点绕,没关系,我们慢慢的来讲.前面Looper一篇讲到了Looper是用于给线程创建消息队列用的,也就是说Looper ...

  10. 十大迷你iPhone天气应用

    来源:GBin1.com 天气特别是指大气情况这样的状态通常包括温度,风,云,湿度和降雨等.上述情况下的天气状况很大程度影响了我们的生活和每天的日常活动.天气可能会经常出乎意料,所以往往希望能够准确提 ...