Android学习笔记之在图片特效

来源:互联网 发布:买mac还是ipad 编辑:程序博客网 时间:2024/05/29 04:48

1、涂鸦(能清屏)

HandWritingActivity.java

[java] view plaincopy
  1. package xiaosi.handWriting;  
  2.   
  3. import android.app.Activity;  
  4. import android.app.AlertDialog;  
  5. import android.content.DialogInterface;  
  6. import android.os.Bundle;  
  7. import android.view.View;  
  8. import android.view.View.OnClickListener;  
  9. import android.widget.Button;  
  10.   
  11. public class HandWritingActivity extends Activity  
  12. {  
  13.     /** Called when the activity is first created. */  
  14.     private HandWrite handWrite = null;  
  15.     private Button clear = null;  
  16.     @Override  
  17.     public void onCreate(Bundle savedInstanceState)  
  18.     {  
  19.         super.onCreate(savedInstanceState);  
  20.         setContentView(R.layout.main);  
  21.           
  22.         handWrite = (HandWrite)findViewById(R.id.handwriteview);  
  23.         clear = (Button)findViewById(R.id.clear);  
  24.         clear.setOnClickListener(new clearListener());  
  25.     }  
  26.        
  27.       
  28.     private class clearListener implements OnClickListener{  
  29.   
  30.         public void onClick(View v)  
  31.         {  
  32.             handWrite.clear();  
  33.         }  
  34.     }  
  35. }  


HandWrite.java

[java] view plaincopy
  1. public class HandWrite extends View  
  2. {  
  3.     private Paint paint = null;  
  4.     private Bitmap originalBitmap = null;  
  5.     private Bitmap new1Bitmap = null;  
  6.     private Bitmap new2Bitmap = null;  
  7.     private float clickX = 0,clickY = 0;  
  8.     private float startX = 0,startY = 0;  
  9.     private boolean isMove = true;  
  10.     private boolean isClear = false;  
  11.     private int color = Color.GREEN;  
  12.     private float strokeWidth = 2.0f;  
  13.     public HandWrite(Context context, AttributeSet attrs)  
  14.     {  
  15.         super(context, attrs);  
  16.         originalBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.girl_a);  
  17.         new1Bitmap = Bitmap.createBitmap(originalBitmap);  
  18.     }  
  19.       
  20.   
  21.     public void clear(){  
  22.         isClear = true;  
  23.         new2Bitmap = Bitmap.createBitmap(originalBitmap);  
  24.         invalidate();  
  25.     }  
  26.     public void setstyle(float strokeWidth){  
  27.         this.strokeWidth = strokeWidth;  
  28.     }  
  29.     @Override  
  30.     protected void onDraw(Canvas canvas)  
  31.     {  
  32.         super.onDraw(canvas);  
  33.         canvas.drawBitmap(HandWriting(new1Bitmap), 00,null);  
  34.           
  35.     }  
  36.   
  37.     public Bitmap HandWriting(Bitmap originalBitmap)  
  38.     {  
  39.         Canvas canvas = null;  
  40.           
  41.         if(isClear){  
  42.             canvas = new Canvas(new2Bitmap);  
  43.         }  
  44.         else{  
  45.             canvas = new Canvas(originalBitmap);  
  46.         }  
  47.         paint = new Paint();  
  48.         paint.setStyle(Style.STROKE);  
  49.         paint.setAntiAlias(true);  
  50.         paint.setColor(color);  
  51.         paint.setStrokeWidth(strokeWidth);  
  52.         if(isMove){  
  53.             canvas.drawLine(startX, startY, clickX, clickY, paint);  
  54.         }  
  55.           
  56.         startX = clickX;  
  57.         startY = clickY;  
  58.           
  59.         if(isClear){  
  60.             return new2Bitmap;  
  61.         }  
  62.         return originalBitmap;  
  63.     }  
  64.   
  65.     @Override  
  66.     public boolean onTouchEvent(MotionEvent event)  
  67.     {  
  68.         clickX = event.getX();  
  69.         clickY = event.getY();  
  70.         if(event.getAction() == MotionEvent.ACTION_DOWN){  
  71.               
  72.             isMove = false;  
  73.             invalidate();  
  74.             return true;  
  75.         }  
  76.         else if(event.getAction() == MotionEvent.ACTION_MOVE){  
  77.               
  78.             isMove = true;  
  79.             invalidate();  
  80.             return true;  
  81.         }  
  82.           
  83.         return super.onTouchEvent(event);  
  84.     }  
  85.      
  86. }  


main.xml

[java] view plaincopy
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     android:layout_width="fill_parent"  
  4.     android:layout_height="fill_parent"  
  5.     android:orientation="vertical" >  
  6.   
  7.     <xiaosi.handWriting.HandWrite  
  8.         android:id="@+id/handwriteview"  
  9.         android:layout_width="fill_parent"  
  10.         android:layout_height="380dp" />  
  11.   
  12.     <LinearLayout  
  13.         android:layout_width="fill_parent"  
  14.         android:layout_height="fill_parent"  
  15.         android:orientation="horizontal"  
  16.         android:gravity="center_horizontal" >  
  17.   
  18.         <Button  
  19.             android:id="@+id/clear"  
  20.             android:layout_width="200dp"  
  21.             android:layout_height="wrap_content"  
  22.             android:text="清屏" />  
  23.           
  24.           
  25.     </LinearLayout>  
  26. </LinearLayout>  

2、得到图片的缩略图


<1>简介

之前往往是通过Bitmap、Drawable和Canvas配合完成,需要写一系列繁杂的逻辑去缩小原有图片,从而得到缩略图。

现在我给大家介绍一种比较简单的方法:(网上有)

在Android 2.2版本中,新增了一个ThumbnailUtils工具类来是实现缩略图,此工具类的功能是强大的,使用是简单,它提供了一个常量和三个方法。利用这些常数和方法,可以轻松快捷的实现图片和视频的缩略图功能。

<2>ThumbnailUtils工具类

常量:

OPTIONS_RECYCLE_INPUT

从此常量用于表示应该回收extractThumbnail(Bitmap, int, int, int)输入源图片(第一个参数),除非输出图片就是输入图片。

 

 

方法:

    Bitmap createVideoThumbnail(String filePath, int kind)

    创建一张视频的缩略图。如果视频已损坏或者格式不支持可能返回null

              参数:

                                filePath: 视频文件路径

                     kind:  文件种类,可以是 MINI_KIND 或 MICRO_KIND

    Bitmap extractThumbnail(Bitmap source, int width, int height, int options)

    创建所需尺寸居中缩放的位图。

    参数:

          source: 需要被创造缩略图的源位图对象

          width: 生成目标的宽度

         height: 生成目标的高度

         options:在缩略图抽取时提供的选项

    Bitmap extractThumbnail(Bitmap source, int width, int height)

    创建所需尺寸居中缩放的位图。

    参数:

        source: 需要被创造缩略图的源位图对象

        width: 生成目标的宽度

        height: 生成目标的高度

 

<3>具体实现:

 

[java] view plaincopy
  1. package xiaosi.thumbnail;  
  2.   
  3. import android.app.Activity;  
  4. import android.graphics.Bitmap;  
  5. import android.graphics.BitmapFactory;  
  6. import android.graphics.drawable.BitmapDrawable;  
  7. import android.graphics.drawable.Drawable;  
  8. import android.media.ThumbnailUtils;  
  9. import android.os.Bundle;  
  10. import android.widget.ImageView;  
  11.   
  12. public class ThumbnailActivity extends Activity {    
  13.     
  14.     private Bitmap bitmap = null;  
  15.     private ImageView image;  
  16.      @Override    
  17.      public void onCreate(Bundle savedInstanceState) {    
  18.         super.onCreate(savedInstanceState);    
  19.         setContentView(R.layout.main);    
  20.         image = (ImageView) findViewById(R.id.image);    
  21.         //得到原图片  
  22.         bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.v);  
  23.         //得到缩略图  
  24.         bitmap = ThumbnailUtils.extractThumbnail(bitmap, 100100);    
  25.         image.setImageBitmap(bitmap);    
  26.     }    
  27. }    


 

main.xml

[java] view plaincopy
  1. <?xml version="1.0" encoding="utf-8"?>  
  2.  <LinearLayout   
  3.      xmlns:android="http://schemas.android.com/apk/res/android"   
  4.      android:orientation="vertical"  
  5.      android:background="#999999"   
  6.      android:layout_width="fill_parent"   
  7.      android:layout_height="fill_parent">  
  8.      <ImageView    
  9.          android:layout_width="wrap_content"   
  10.          android:layout_height="wrap_content"   
  11.          android:src="@drawable/v"  
  12.          android:layout_marginLeft="10dip"/>  
  13.      <TextView    
  14.          android:layout_width="wrap_content"   
  15.          android:layout_height="wrap_content"   
  16.          android:text="缩略图:"   
  17.          android:textColor="#000000"/>  
  18.      <ImageView android:id="@+id/image"   
  19.          android:layout_width="wrap_content"   
  20.          android:layout_height="wrap_content"  
  21.          android:layout_marginLeft="10dip"/>  
  22.  </LinearLayout>  

3、给图片加边框

 

[java] view plaincopy
  1. //设置颜色  
  2.     public void setColour(int color){  
  3.         co = color;  
  4.     }  
  5.     //设置边框宽度  
  6.     public void setBorderWidth(int width){  
  7.           
  8.         borderwidth = width;  
  9.     }  


 

具体实现:

[java] view plaincopy
  1. package xiaosi.imageborder;  
  2.   
  3. import android.app.Activity;  
  4. import android.graphics.Color;  
  5. import android.os.Bundle;  
  6.   
  7. public class ImageBorderActivity extends Activity {  
  8.     /** Called when the activity is first created. */  
  9.     private myImageView image = null;  
  10.     private myImageView image1 = null;  
  11.     @Override  
  12.     public void onCreate(Bundle savedInstanceState) {  
  13.         super.onCreate(savedInstanceState);  
  14.         setContentView(R.layout.main);  
  15.           
  16.         image = (myImageView)findViewById(R.id.iamge);  
  17.         image.setColour(Color.YELLOW);  
  18.         image.setBorderWidth(10);  
  19.         image1 = (myImageView)findViewById(R.id.iamge1);  
  20.         image1.setColour(Color.GREEN);  
  21.         image1.setBorderWidth(5);  
  22.     }  
  23. }  


 

 

main.xml

[java] view plaincopy
  1. <LinearLayout  
  2.     xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     android:background="@drawable/playerbackground"  
  4.     android:layout_width="fill_parent"  
  5.     android:layout_height="fill_parent">  
  6.      <xiaosi.imageborder.myImageView   
  7.          android:id="@+id/iamge"  
  8.          android:layout_width="200px"   
  9.          android:layout_height="230px"  
  10.          android:layout_alignParentRight="true"  
  11.          android:src="@drawable/v"  
  12.          android:layout_centerInParent="true"  
  13.          android:layout_marginRight="3px"  
  14.         />  
  15.      <xiaosi.imageborder.myImageView   
  16.          android:id="@+id/iamge1"  
  17.          android:layout_width="200px"   
  18.          android:layout_height="230px"  
  19.          android:layout_alignParentRight="true"  
  20.          android:src="@drawable/v"  
  21.          android:layout_centerInParent="true"  
  22.          android:layout_marginRight="3px"  
  23.         />  
  24. </LinearLayout>  


 

[java] view plaincopy
  1. package xiaosi.imageborder;  
  2.   
  3. import android.content.Context;  
  4. import android.graphics.Canvas;  
  5. import android.graphics.Paint;  
  6. import android.graphics.Rect;  
  7. import android.util.AttributeSet;  
  8. import android.widget.ImageView;  
  9.   
  10. public class myImageView extends ImageView {  
  11.   
  12.     private int co;  
  13.     private int borderwidth;  
  14.     public myImageView(Context context) {  
  15.         super(context);  
  16.     }  
  17.     public myImageView(Context context, AttributeSet attrs,  
  18.             int defStyle) {  
  19.         super(context, attrs, defStyle);  
  20.     }  
  21.   
  22.     public myImageView(Context context, AttributeSet attrs) {  
  23.         super(context, attrs);  
  24.     }  
  25.     //设置颜色  
  26.     public void setColour(int color){  
  27.         co = color;  
  28.     }  
  29.     //设置边框宽度  
  30.     public void setBorderWidth(int width){  
  31.           
  32.         borderwidth = width;  
  33.     }  
  34.     @Override  
  35.     protected void onDraw(Canvas canvas) {  
  36.         super.onDraw(canvas);  
  37.         // 画边框  
  38.         Rect rec = canvas.getClipBounds();  
  39.         rec.bottom--;  
  40.         rec.right--;  
  41.         Paint paint = new Paint();  
  42.         //设置边框颜色  
  43.         paint.setColor(co);  
  44.         paint.setStyle(Paint.Style.STROKE);  
  45.         //设置边框宽度  
  46.         paint.setStrokeWidth(borderwidth);  
  47.         canvas.drawRect(rec, paint);  
  48.     }  
  49. }  

4、画图并保存图片到本地

1、首先创建一个Bitmap图片,并指定大小;
 
2、在该图片上创建一个新的画布Canvas,然后在画布上绘制,并保存即可;
 
3、需要保存的目录File,注意如果写的目录如“/sdcard/song/”如果不存在的话,要先创建(file.mkdirs).。


4、需要添加权限:<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

Canvas是一个画布,你可以建立一个空白的画布,就直接new一个Canvas对象,不需要参数。也可以先使用BitmapFactory创建一个Bitmap对象,作为新的Canvas对象的参数,也就是说这个画布不是空白的,如果你想保存图片的话,最好是Bitmap是一个新的,而不是从某个文件中读入进来的,或者是Drawable对象。然后使用Canvas画第一张图上去,在画第二张图上去,最后使用Canvas.save(int flag)的方法进行保存,注意save方法里面的参数可以保存单个图层,如果是保存全部图层的 话使用 save( Canvas.ALL_SAVE_FLAG )。

 

关于图片旋转问题不懂的话,请看博文:Android学习笔记之Bitmap位图的旋转 
                                这是原图片和旋转后图片

 

                                                                     这是保存到本地的图片800*600 JPG格式

 

具体实现:

[java] view plaincopy
  1. package xiaosi.bitmap;  
  2.   
  3. import android.app.Activity;  
  4. import android.os.Bundle;  
  5.   
  6. public class mianActivity extends Activity  
  7. {  
  8.   
  9.     private BitmapView bitmapView = null;  
  10.     @Override  
  11.     protected void onCreate(Bundle savedInstanceState)  
  12.     {  
  13.         super.onCreate(savedInstanceState);  
  14.         bitmapView = new BitmapView(this);  
  15.         setContentView(bitmapView);  
  16.     }  
  17. }  


BitmapView.java

[java] view plaincopy
  1. package xiaosi.bitmap;  
  2.   
  3. import java.io.File;  
  4. import java.io.FileOutputStream;  
  5.   
  6. import android.content.Context;  
  7. import android.content.res.Resources;  
  8. import android.graphics.Bitmap;  
  9. import android.graphics.Bitmap.Config;  
  10. import android.graphics.BitmapFactory;  
  11. import android.graphics.Canvas;  
  12. import android.graphics.Color;  
  13. import android.graphics.Matrix;  
  14. import android.view.View;  
  15.   
  16. public class BitmapView extends View  
  17. {  
  18.     private Matrix matrix = null;  
  19.     public BitmapView(Context context)  
  20.     {  
  21.         super(context);  
  22.     }  
  23.   
  24.     public void onDraw(Canvas canvas)  
  25.     {  
  26.           
  27.         // 获取资源文件的引用res  
  28.         Resources res = getResources();   
  29.         // 获取图形资源文件  
  30.         Bitmap bmp = BitmapFactory.decodeResource(res, R.drawable.h);  
  31.         // 设置canvas画布背景为白色  
  32.         canvas.drawColor(Color.BLACK);  
  33.         canvas.drawBitmap(bmp, 00null);  
  34.         // 定义矩阵对象  
  35.         matrix = new Matrix();  
  36.         //旋转30度  
  37.         matrix.postRotate(30);  
  38.         Bitmap bitmap = Bitmap.createBitmap(bmp, 050, bmp.getWidth(), bmp.getHeight()/2,  
  39.                 matrix, true);  
  40.         canvas.drawBitmap(bitmap, 0250null);  
  41.         SaveBitmap(bitmap);  
  42.     }  
  43.     //保存到本地  
  44.     public void SaveBitmap(Bitmap bmp)  
  45.     {  
  46.         Bitmap bitmap = Bitmap.createBitmap(800600, Config.ARGB_8888);    
  47.         Canvas canvas = new Canvas(bitmap);  
  48.         //加载背景图片  
  49.         Bitmap bmps = BitmapFactory.decodeResource(getResources(), R.drawable.playerbackground);  
  50.         canvas.drawBitmap(bmps, 00null);  
  51.         //加载要保存的画面  
  52.         canvas.drawBitmap(bmp, 10100null);  
  53.         //保存全部图层  
  54.         canvas.save(Canvas.ALL_SAVE_FLAG);  
  55.         canvas.restore();  
  56.         //存储路径  
  57.         File file = new File("/sdcard/song/");  
  58.         if(!file.exists())  
  59.             file.mkdirs();  
  60.             try {  
  61.                 FileOutputStream fileOutputStream = new FileOutputStream(file.getPath() + "/xuanzhuan.jpg");  
  62.                 bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fileOutputStream);  
  63.                 fileOutputStream.close();  
  64.                 System.out.println("saveBmp is here");  
  65.             } catch (Exception e) {  
  66.                         e.printStackTrace();  
  67.         }  
  68.     }  
  69. }  

5、图片色调饱和度、色相、亮度处理

原图:


处理后:


下面贴代码:

一、图片处理层:

[java] view plaincopy
  1. package com.jacp.tone.view;  
  2.   
  3. import java.util.ArrayList;  
  4.   
  5. import android.content.Context;  
  6. import android.graphics.Bitmap;  
  7. import android.graphics.Canvas;  
  8. import android.graphics.ColorMatrix;  
  9. import android.graphics.ColorMatrixColorFilter;  
  10. import android.graphics.Paint;  
  11. import android.view.Gravity;  
  12. import android.view.View;  
  13. import android.widget.LinearLayout;  
  14. import android.widget.SeekBar;  
  15. import android.widget.SeekBar.OnSeekBarChangeListener;  
  16. import android.widget.TextView;  
  17.   
  18. import com.jacp.tone.R;  
  19.   
  20. /** 
  21.  * 图片调色处理 
  22.  * @author maylian7700@126.com 
  23.  * 
  24.  */  
  25. public class ToneLayer {  
  26.       
  27.     /** 
  28.      * 饱和度标识 
  29.      */  
  30.     public static final int FLAG_SATURATION = 0x0;  
  31.       
  32.     /** 
  33.      * 亮度标识 
  34.      */  
  35.     public static final int FLAG_LUM = 0x1;  
  36.       
  37.     /** 
  38.      * 色相标识 
  39.      */  
  40.     public static final int FLAG_HUE = 0x2;  
  41.       
  42.     /** 
  43.      * 饱和度 
  44.      */  
  45.     private TextView mSaturation;  
  46.     private SeekBar mSaturationBar;  
  47.   
  48.     /** 
  49.      * 色相 
  50.      */  
  51.     private TextView mHue;  
  52.     private SeekBar mHueBar;  
  53.   
  54.     /** 
  55.      * 亮度 
  56.      */  
  57.     private TextView mLum;  
  58.     private SeekBar mLumBar;  
  59.   
  60.     private float mDensity;  
  61.     private static final int TEXT_WIDTH = 50;  
  62.   
  63.     private LinearLayout mParent;  
  64.   
  65.     private ColorMatrix mLightnessMatrix;  
  66.     private ColorMatrix mSaturationMatrix;  
  67.     private ColorMatrix mHueMatrix;  
  68.     private ColorMatrix mAllMatrix;  
  69.   
  70.     /** 
  71.      * 亮度 
  72.      */  
  73.     private float mLumValue = 1F;  
  74.   
  75.     /** 
  76.      * 饱和度 
  77.      */  
  78.     private float mSaturationValue = 0F;  
  79.   
  80.     /** 
  81.      * 色相 
  82.      */  
  83.     private float mHueValue = 0F;  
  84.       
  85.     /** 
  86.      * SeekBar的中间值 
  87.      */  
  88.     private static final int MIDDLE_VALUE = 127;  
  89.       
  90.     /** 
  91.      * SeekBar的最大值 
  92.      */  
  93.     private static final int MAX_VALUE = 255;  
  94.       
  95.     private ArrayList<SeekBar> mSeekBars = new ArrayList<SeekBar>();  
  96.   
  97.     public ToneLayer(Context context) {  
  98.         init(context);  
  99.     }  
  100.   
  101.     private void init(Context context) {  
  102.         mDensity = context.getResources().getDisplayMetrics().density;  
  103.   
  104.         mSaturation = new TextView(context);  
  105.         mSaturation.setText(R.string.saturation);  
  106.         mHue = new TextView(context);  
  107.         mHue.setText(R.string.contrast);  
  108.         mLum = new TextView(context);  
  109.         mLum.setText(R.string.lightness);  
  110.           
  111.         mSaturationBar = new SeekBar(context);  
  112.         mHueBar = new SeekBar(context);  
  113.         mLumBar = new SeekBar(context);  
  114.           
  115.         mSeekBars.add(mSaturationBar);  
  116.         mSeekBars.add(mHueBar);  
  117.         mSeekBars.add(mLumBar);  
  118.           
  119.         for (int i = 0, size = mSeekBars.size(); i < size; i++) {  
  120.             SeekBar seekBar = mSeekBars.get(i);  
  121.             seekBar.setMax(MAX_VALUE);  
  122.             seekBar.setProgress(MIDDLE_VALUE);  
  123.             seekBar.setTag(i);  
  124.         }  
  125.   
  126.         LinearLayout saturation = new LinearLayout(context);  
  127.         saturation.setOrientation(LinearLayout.HORIZONTAL);  
  128.         saturation.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT));  
  129.   
  130.         LinearLayout.LayoutParams txtLayoutparams = new LinearLayout.LayoutParams((int) (TEXT_WIDTH * mDensity), LinearLayout.LayoutParams.MATCH_PARENT);  
  131.         mSaturation.setGravity(Gravity.CENTER);  
  132.         saturation.addView(mSaturation, txtLayoutparams);  
  133.   
  134.         LinearLayout.LayoutParams seekLayoutparams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT);  
  135.         saturation.addView(mSaturationBar, seekLayoutparams);  
  136.   
  137.         LinearLayout hue = new LinearLayout(context);  
  138.         hue.setOrientation(LinearLayout.HORIZONTAL);  
  139.         hue.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT));  
  140.   
  141.         mHue.setGravity(Gravity.CENTER);  
  142.         hue.addView(mHue, txtLayoutparams);  
  143.         hue.addView(mHueBar, seekLayoutparams);  
  144.   
  145.         LinearLayout lum = new LinearLayout(context);  
  146.         lum.setOrientation(LinearLayout.HORIZONTAL);  
  147.         lum.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT));  
  148.   
  149.         mLum.setGravity(Gravity.CENTER);  
  150.         lum.addView(mLum, txtLayoutparams);  
  151.         lum.addView(mLumBar, seekLayoutparams);  
  152.   
  153.         mParent = new LinearLayout(context);  
  154.         mParent.setOrientation(LinearLayout.VERTICAL);  
  155.         mParent.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT));  
  156.         mParent.addView(saturation);  
  157.         mParent.addView(hue);  
  158.         mParent.addView(lum);  
  159.     }  
  160.   
  161.     public View getParentView() {  
  162.         return mParent;  
  163.     }  
  164.   
  165.     /** 
  166.      * 设置饱和度值 
  167.      * @param saturation 
  168.      */  
  169.     public void setSaturation(int saturation) {  
  170.         mSaturationValue = saturation * 1.0F / MIDDLE_VALUE;  
  171.     }  
  172.   
  173.     /** 
  174.      * 设置色相值 
  175.      * @param hue 
  176.      */  
  177.     public void setHue(int hue) {  
  178.         mHueValue = hue * 1.0F / MIDDLE_VALUE;  
  179.     }  
  180.   
  181.     /** 
  182.      * 设置亮度值 
  183.      * @param lum 
  184.      */  
  185.     public void setLum(int lum) {  
  186.         mLumValue = (lum - MIDDLE_VALUE) * 1.0F / MIDDLE_VALUE * 180;  
  187.     }  
  188.   
  189.     public ArrayList<SeekBar> getSeekBars()  
  190.     {  
  191.         return mSeekBars;  
  192.     }  
  193.   
  194.     /** 
  195.      *  
  196.      * @param flag 
  197.      *            比特位0 表示是否改变色相,比位1表示是否改变饱和度,比特位2表示是否改变明亮度 
  198.      */  
  199.     public Bitmap handleImage(Bitmap bm, int flag) {  
  200.         Bitmap bmp = Bitmap.createBitmap(bm.getWidth(), bm.getHeight(),  
  201.                 Bitmap.Config.ARGB_8888);  
  202.         // 创建一个相同尺寸的可变的位图区,用于绘制调色后的图片  
  203.         Canvas canvas = new Canvas(bmp); // 得到画笔对象  
  204.         Paint paint = new Paint(); // 新建paint  
  205.         paint.setAntiAlias(true); // 设置抗锯齿,也即是边缘做平滑处理  
  206.         if (null == mAllMatrix) {  
  207.             mAllMatrix = new ColorMatrix();  
  208.         }  
  209.   
  210.         if (null == mLightnessMatrix) {  
  211.             mLightnessMatrix = new ColorMatrix(); // 用于颜色变换的矩阵,android位图颜色变化处理主要是靠该对象完成  
  212.         }  
  213.   
  214.         if (null == mSaturationMatrix) {  
  215.             mSaturationMatrix = new ColorMatrix();  
  216.         }  
  217.   
  218.         if (null == mHueMatrix) {  
  219.             mHueMatrix = new ColorMatrix();  
  220.         }  
  221.   
  222.         switch (flag) {  
  223.         case FLAG_HUE: // 需要改变色相  
  224.             mHueMatrix.reset();  
  225.             mHueMatrix.setScale(mHueValue, mHueValue, mHueValue, 1); // 红、绿、蓝三分量按相同的比例,最后一个参数1表示透明度不做变化,此函数详细说明参考  
  226.             // // android  
  227.             // doc  
  228.             break;  
  229.         case FLAG_SATURATION: // 需要改变饱和度  
  230.             // saturation 饱和度值,最小可设为0,此时对应的是灰度图(也就是俗话的“黑白图”),  
  231.             // 为1表示饱和度不变,设置大于1,就显示过饱和  
  232.             mSaturationMatrix.reset();  
  233.             mSaturationMatrix.setSaturation(mSaturationValue);  
  234.             break;  
  235.         case FLAG_LUM: // 亮度  
  236.             // hueColor就是色轮旋转的角度,正值表示顺时针旋转,负值表示逆时针旋转  
  237.             mLightnessMatrix.reset(); // 设为默认值  
  238.             mLightnessMatrix.setRotate(0, mLumValue); // 控制让红色区在色轮上旋转的角度  
  239.             mLightnessMatrix.setRotate(1, mLumValue); // 控制让绿红色区在色轮上旋转的角度  
  240.             mLightnessMatrix.setRotate(2, mLumValue); // 控制让蓝色区在色轮上旋转的角度  
  241.             // 这里相当于改变的是全图的色相  
  242.             break;  
  243.         }  
  244.         mAllMatrix.reset();  
  245.         mAllMatrix.postConcat(mHueMatrix);  
  246.         mAllMatrix.postConcat(mSaturationMatrix); // 效果叠加  
  247.         mAllMatrix.postConcat(mLightnessMatrix); // 效果叠加  
  248.   
  249.         paint.setColorFilter(new ColorMatrixColorFilter(mAllMatrix));// 设置颜色变换效果  
  250.         canvas.drawBitmap(bm, 00, paint); // 将颜色变化后的图片输出到新创建的位图区  
  251.         // 返回新的位图,也即调色处理后的图片  
  252.         return bmp;  
  253.     }  
  254.   
  255. }  


二、主界面:

[java] view plaincopy
  1. package com.jacp.tone;  
  2.   
  3. import java.util.ArrayList;  
  4.   
  5. import android.app.Activity;  
  6. import android.graphics.Bitmap;  
  7. import android.graphics.BitmapFactory;  
  8. import android.os.Bundle;  
  9. import android.widget.ImageView;  
  10. import android.widget.LinearLayout;  
  11. import android.widget.SeekBar;  
  12. import android.widget.SeekBar.OnSeekBarChangeListener;  
  13.   
  14. import com.jacp.tone.view.ToneLayer;  
  15.   
  16. /** 
  17.  * 启动的主界面 
  18.  * @author maylian7700@126.com 
  19.  * 
  20.  */  
  21. public class ImageToneActivity extends Activity implements OnSeekBarChangeListener {  
  22.     private ToneLayer mToneLayer;  
  23.     private ImageView mImageView;  
  24.     private Bitmap mBitmap;  
  25.       
  26.     @Override  
  27.     public void onCreate(Bundle savedInstanceState) {  
  28.         super.onCreate(savedInstanceState);  
  29.         setContentView(R.layout.main);  
  30.           
  31.         init();  
  32.     }  
  33.       
  34.     private void init()  
  35.     {  
  36.         mToneLayer = new ToneLayer(this);  
  37.           
  38.         mBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.test);  
  39.         mImageView = (ImageView) findViewById(R.id.img_view);  
  40.         mImageView.setImageBitmap(mBitmap);  
  41.         ((LinearLayout) findViewById(R.id.tone_view)).addView(mToneLayer.getParentView());  
  42.           
  43.         ArrayList<SeekBar> seekBars = mToneLayer.getSeekBars();  
  44.         for (int i = 0, size = seekBars.size(); i < size; i++)  
  45.         {  
  46.             seekBars.get(i).setOnSeekBarChangeListener(this);  
  47.         }  
  48.     }  
  49.   
  50.     @Override  
  51.     public void onProgressChanged(SeekBar seekBar, int progress,  
  52.             boolean fromUser) {  
  53.         int flag = (Integer) seekBar.getTag();  
  54.         switch (flag)  
  55.         {  
  56.         case ToneLayer.FLAG_SATURATION:  
  57.             mToneLayer.setSaturation(progress);  
  58.             break;  
  59.         case ToneLayer.FLAG_LUM:  
  60.             mToneLayer.setLum(progress);  
  61.             break;  
  62.         case ToneLayer.FLAG_HUE:  
  63.             mToneLayer.setHue(progress);  
  64.             break;  
  65.         }  
  66.           
  67.         mImageView.setImageBitmap(mToneLayer.handleImage(mBitmap, flag));  
  68.     }  
  69.   
  70.     @Override  
  71.     public void onStartTrackingTouch(SeekBar seekBar) {  
  72.           
  73.     }  
  74.   
  75.     @Override  
  76.     public void onStopTrackingTouch(SeekBar seekBar) {  
  77.           
  78.     }  
  79. }  


三、布局文件:

[java] view plaincopy
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <ScrollView xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     android:layout_width="match_parent"  
  4.     android:layout_height="match_parent"  
  5.     >  
  6.       
  7.     <LinearLayout   
  8.         android:layout_width="match_parent"  
  9.         android:layout_height="match_parent"  
  10.         android:orientation="vertical" >  
  11.       
  12.         <ImageView  
  13.             android:layout_width="wrap_content"  
  14.             android:layout_height="wrap_content"  
  15.             android:layout_weight="1"  
  16.             android:id="@+id/img_view"  
  17.             android:layout_gravity="center"  
  18.             />  
  19.         <LinearLayout  
  20.             android:layout_width="match_parent"  
  21.             android:layout_height="wrap_content"  
  22.             android:id="@+id/tone_view"  
  23.             />  
  24.     </LinearLayout>  
  25. </ScrollView>  
6、模糊效果

这篇将讲到图片特效处理的模糊效果。跟前面一样是对像素点进行处理,算法是通用的,但耗时会更长,至于为什么,看了下面的代码你就会明白。

算法:

一、简单算法:将像素点周围八个点包括自身一共九个点的RGB值分别相加后平均,作为当前像素点的RGB值,即可实现效果。

举例:

ABC

DEF

GHI

假如当前点是E,那么会有:

[java] view plaincopy
  1. E.r = (A.r + B.r + C.r + D.r + E.r + F.r + G.r + H.r + I.r) /9  // r表示的是E像素点RGB值的R值 
[java] view plaincopy
  1. E.r = (A.r + B.r + C.r + D.r + E.r + F.r + G.r + H.r + I.r) / 9  // r表示的是E像素点RGB值的R值  

E像素点的GB值类似。

二、采用高斯模糊:

高斯矩阵:

[java] view plaincopy
  1. int[] gauss = new int[] { 121242121 }; 
[java] view plaincopy
  1. int[] gauss = new int[] { 121242121 };  
算法是:将九个点的RGB值分别与高斯矩阵中的对应项相乘的和,然后再除以一个相应的值作为当前像素点的RGB值。

举例:(还是上面的九个点)
假如当前点是E,那么会有:

[java] view plaincopy
  1. int delta = 16
  2. E.r =( A.r * gauss[0] + B.r * gauss[1] + C.r * gauss[2] + D.r * gauss[3] + E.r * gauss[4] + F.r * gauss[5] + G.r * gauss[6] + H.r * gauss[7] + I.r * gauss[8]) / delta 
[java] view plaincopy
  1. int delta = 16;  
  2. E.r =( A.r * gauss[0] + B.r * gauss[1] + C.r * gauss[2] + D.r * gauss[3] + E.r * gauss[4] + F.r * gauss[5] + G.r * gauss[6] + H.r * gauss[7] + I.r * gauss[8]) / delta  
E像素点的GB值类似,delta的取值貌似没有规定值,可以自己设置任意值,但要想达到效果,能设的值很少,下面图片是值为16的效果。
处理效果:

原图片:


处理后:

两种处理方式的代码:

[java] view plaincopy
  1. /**
  2.      * 模糊效果
  3.      * @param bmp
  4.      * @return
  5.      */ 
  6.     private Bitmap blurImage(Bitmap bmp) 
  7.     { 
  8.         int width = bmp.getWidth(); 
  9.         int height = bmp.getHeight(); 
  10.         Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565); 
  11.          
  12.         int pixColor = 0
  13.          
  14.         int newR = 0
  15.         int newG = 0
  16.         int newB = 0
  17.          
  18.         int newColor = 0
  19.          
  20.         int[][] colors = new int[9][3]; 
  21.         for (int i = 1, length = width - 1; i < length; i++) 
  22.         { 
  23.             for (int k = 1, len = height - 1; k < len; k++) 
  24.             { 
  25.                 for (int m = 0; m < 9; m++) 
  26.                 { 
  27.                     int s = 0
  28.                     int p = 0
  29.                     switch(m) 
  30.                     { 
  31.                     case 0
  32.                         s = i - 1
  33.                         p = k - 1
  34.                         break
  35.                     case 1
  36.                         s = i; 
  37.                         p = k - 1
  38.                         break
  39.                     case 2
  40.                         s = i + 1
  41.                         p = k - 1
  42.                         break
  43.                     case 3
  44.                         s = i + 1
  45.                         p = k; 
  46.                         break
  47.                     case 4
  48.                         s = i + 1
  49.                         p = k + 1
  50.                         break
  51.                     case 5
  52.                         s = i; 
  53.                         p = k + 1
  54.                         break
  55.                     case 6
  56.                         s = i - 1
  57.                         p = k + 1
  58.                         break
  59.                     case 7
  60.                         s = i - 1
  61.                         p = k; 
  62.                         break
  63.                     case 8
  64.                         s = i; 
  65.                         p = k; 
  66.                     } 
  67.                     pixColor = bmp.getPixel(s, p); 
  68.                     colors[m][0] = Color.red(pixColor); 
  69.                     colors[m][1] = Color.green(pixColor); 
  70.                     colors[m][2] = Color.blue(pixColor); 
  71.                 } 
  72.                  
  73.                 for (int m = 0; m < 9; m++) 
  74.                 { 
  75.                     newR += colors[m][0]; 
  76.                     newG += colors[m][1]; 
  77.                     newB += colors[m][2]; 
  78.                 } 
  79.                  
  80.                 newR = (int) (newR / 9F); 
  81.                 newG = (int) (newG / 9F); 
  82.                 newB = (int) (newB / 9F); 
  83.                  
  84.                 newR = Math.min(255, Math.max(0, newR)); 
  85.                 newG = Math.min(255, Math.max(0, newG)); 
  86.                 newB = Math.min(255, Math.max(0, newB)); 
  87.                  
  88.                 newColor = Color.argb(255, newR, newG, newB); 
  89.                 bitmap.setPixel(i, k, newColor); 
  90.                  
  91.                 newR = 0
  92.                 newG = 0
  93.                 newB = 0
  94.             } 
  95.         } 
  96.          
  97.         return bitmap; 
  98.     } 
  99.      
  100.     /**
  101.      * 柔化效果(高斯模糊)(优化后比上面快三倍)
  102.      * @param bmp
  103.      * @return
  104.      */ 
  105.     private Bitmap blurImageAmeliorate(Bitmap bmp) 
  106.     { 
  107.         long start = System.currentTimeMillis(); 
  108.         // 高斯矩阵 
  109.         int[] gauss = new int[] { 121242121 }; 
  110.          
  111.         int width = bmp.getWidth(); 
  112.         int height = bmp.getHeight(); 
  113.         Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565); 
  114.          
  115.         int pixR = 0
  116.         int pixG = 0
  117.         int pixB = 0
  118.          
  119.         int pixColor = 0
  120.          
  121.         int newR = 0
  122.         int newG = 0
  123.         int newB = 0
  124.          
  125.         int delta = 16// 值越小图片会越亮,越大则越暗 
  126.          
  127.         int idx = 0
  128.         int[] pixels = new int[width * height]; 
  129.         bmp.getPixels(pixels, 0, width, 00, width, height); 
  130.         for (int i = 1, length = height - 1; i < length; i++) 
  131.         { 
  132.             for (int k = 1, len = width - 1; k < len; k++) 
  133.             { 
  134.                 idx = 0
  135.                 for (int m = -1; m <= 1; m++) 
  136.                 { 
  137.                     for (int n = -1; n <= 1; n++) 
  138.                     { 
  139.                         pixColor = pixels[(i + m) * width + k + n]; 
  140.                         pixR = Color.red(pixColor); 
  141.                         pixG = Color.green(pixColor); 
  142.                         pixB = Color.blue(pixColor); 
  143.                          
  144.                         newR = newR + (int) (pixR * gauss[idx]); 
  145.                         newG = newG + (int) (pixG * gauss[idx]); 
  146.                         newB = newB + (int) (pixB * gauss[idx]); 
  147.                         idx++; 
  148.                     } 
  149.                 } 
  150.                  
  151.                 newR /= delta; 
  152.                 newG /= delta; 
  153.                 newB /= delta; 
  154.                  
  155.                 newR = Math.min(255, Math.max(0, newR)); 
  156.                 newG = Math.min(255, Math.max(0, newG)); 
  157.                 newB = Math.min(255, Math.max(0, newB)); 
  158.                  
  159.                 pixels[i * width + k] = Color.argb(255, newR, newG, newB); 
  160.                  
  161.                 newR = 0
  162.                 newG = 0
  163.                 newB = 0
  164.             } 
  165.         } 
  166.          
  167.         bitmap.setPixels(pixels, 0, width, 00, width, height); 
  168.         long end = System.currentTimeMillis(); 
  169.         Log.d("may""used time="+(end - start)); 
  170.         return bitmap; 
  171.     } 
[java] view plaincopy
  1. /** 
  2.      * 模糊效果 
  3.      * @param bmp 
  4.      * @return 
  5.      */  
  6.     private Bitmap blurImage(Bitmap bmp)  
  7.     {  
  8.         int width = bmp.getWidth();  
  9.         int height = bmp.getHeight();  
  10.         Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565);  
  11.           
  12.         int pixColor = 0;  
  13.           
  14.         int newR = 0;  
  15.         int newG = 0;  
  16.         int newB = 0;  
  17.           
  18.         int newColor = 0;  
  19.           
  20.         int[][] colors = new int[9][3];  
  21.         for (int i = 1, length = width - 1; i < length; i++)  
  22.         {  
  23.             for (int k = 1, len = height - 1; k < len; k++)  
  24.             {  
  25.                 for (int m = 0; m < 9; m++)  
  26.                 {  
  27.                     int s = 0;  
  28.                     int p = 0;  
  29.                     switch(m)  
  30.                     {  
  31.                     case 0:  
  32.                         s = i - 1;  
  33.                         p = k - 1;  
  34.                         break;  
  35.                     case 1:  
  36.                         s = i;  
  37.                         p = k - 1;  
  38.                         break;  
  39.                     case 2:  
  40.                         s = i + 1;  
  41.                         p = k - 1;  
  42.                         break;  
  43.                     case 3:  
  44.                         s = i + 1;  
  45.                         p = k;  
  46.                         break;  
  47.                     case 4:  
  48.                         s = i + 1;  
  49.                         p = k + 1;  
  50.                         break;  
  51.                     case 5:  
  52.                         s = i;  
  53.                         p = k + 1;  
  54.                         break;  
  55.                     case 6:  
  56.                         s = i - 1;  
  57.                         p = k + 1;  
  58.                         break;  
  59.                     case 7:  
  60.                         s = i - 1;  
  61.                         p = k;  
  62.                         break;  
  63.                     case 8:  
  64.                         s = i;  
  65.                         p = k;  
  66.                     }  
  67.                     pixColor = bmp.getPixel(s, p);  
  68.                     colors[m][0] = Color.red(pixColor);  
  69.                     colors[m][1] = Color.green(pixColor);  
  70.                     colors[m][2] = Color.blue(pixColor);  
  71.                 }  
  72.                   
  73.                 for (int m = 0; m < 9; m++)  
  74.                 {  
  75.                     newR += colors[m][0];  
  76.                     newG += colors[m][1];  
  77.                     newB += colors[m][2];  
  78.                 }  
  79.                   
  80.                 newR = (int) (newR / 9F);  
  81.                 newG = (int) (newG / 9F);  
  82.                 newB = (int) (newB / 9F);  
  83.                   
  84.                 newR = Math.min(255, Math.max(0, newR));  
  85.                 newG = Math.min(255, Math.max(0, newG));  
  86.                 newB = Math.min(255, Math.max(0, newB));  
  87.                   
  88.                 newColor = Color.argb(255, newR, newG, newB);  
  89.                 bitmap.setPixel(i, k, newColor);  
  90.                   
  91.                 newR = 0;  
  92.                 newG = 0;  
  93.                 newB = 0;  
  94.             }  
  95.         }  
  96.           
  97.         return bitmap;  
  98.     }  
  99.       
  100.     /** 
  101.      * 柔化效果(高斯模糊)(优化后比上面快三倍) 
  102.      * @param bmp 
  103.      * @return 
  104.      */  
  105.     private Bitmap blurImageAmeliorate(Bitmap bmp)  
  106.     {  
  107.         long start = System.currentTimeMillis();  
  108.         // 高斯矩阵  
  109.         int[] gauss = new int[] { 121242121 };  
  110.           
  111.         int width = bmp.getWidth();  
  112.         int height = bmp.getHeight();  
  113.         Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565);  
  114.           
  115.         int pixR = 0;  
  116.         int pixG = 0;  
  117.         int pixB = 0;  
  118.           
  119.         int pixColor = 0;  
  120.           
  121.         int newR = 0;  
  122.         int newG = 0;  
  123.         int newB = 0;  
  124.           
  125.         int delta = 16// 值越小图片会越亮,越大则越暗  
  126.           
  127.         int idx = 0;  
  128.         int[] pixels = new int[width * height];  
  129.         bmp.getPixels(pixels, 0, width, 00, width, height);  
  130.         for (int i = 1, length = height - 1; i < length; i++)  
  131.         {  
  132.             for (int k = 1, len = width - 1; k < len; k++)  
  133.             {  
  134.                 idx = 0;  
  135.                 for (int m = -1; m <= 1; m++)  
  136.                 {  
  137.                     for (int n = -1; n <= 1; n++)  
  138.                     {  
  139.                         pixColor = pixels[(i + m) * width + k + n];  
  140.                         pixR = Color.red(pixColor);  
  141.                         pixG = Color.green(pixColor);  
  142.                         pixB = Color.blue(pixColor);  
  143.                           
  144.                         newR = newR + (int) (pixR * gauss[idx]);  
  145.                         newG = newG + (int) (pixG * gauss[idx]);  
  146.                         newB = newB + (int) (pixB * gauss[idx]);  
  147.                         idx++;  
  148.                     }  
  149.                 }  
  150.                   
  151.                 newR /= delta;  
  152.                 newG /= delta;  
  153.                 newB /= delta;  
  154.                   
  155.                 newR = Math.min(255, Math.max(0, newR));  
  156.                 newG = Math.min(255, Math.max(0, newG));  
  157.                 newB = Math.min(255, Math.max(0, newB));  
  158.                   
  159.                 pixels[i * width + k] = Color.argb(255, newR, newG, newB);  
  160.                   
  161.                 newR = 0;  
  162.                 newG = 0;  
  163.                 newB = 0;  
  164.             }  
  165.         }  
  166.           
  167.         bitmap.setPixels(pixels, 0, width, 00, width, height);  
  168.         long end = System.currentTimeMillis();  
  169.         Log.d("may""used time="+(end - start));  
  170.         return bitmap;  
  171.     }  

 

在优化后的代码中要注意了,pixels数组不能超过规定的大小,也就是说图片的尺寸不能太大,否则会栈内存溢出。

7、锐化效果

这篇将讲到图片特效处理的锐化效果。跟前面一样是对像素点进行处理,算法是通用的。

算法原理:

一、简单算法:分别获取当前像素点和八个周围像素点的RGB值,先求出当前像素点的RGB值与八个像素点RGB值的和的平均数,再乘以相应的系数,然后在与当前像素点之和。

例:

ABC

DEF

GHI

对E点进行锐化:

[java] view plaincopy
  1. float delta = 0.3
  2. E.r = (E.r - (A.r + B.r + C.r + D.r + F.r + G.r + H.r + I.r) / 8) * delta + E.r; 
[java] view plaincopy
  1. float delta = 0.3;  
  2. E.r = (E.r - (A.r + B.r + C.r + D.r + F.r + G.r + H.r + I.r) / 8) * delta + E.r;  

 

E.g,E.b类似,delta建议取0.3,具体多少无所谓,试一下就知道了。但按照上面原理,没有达到预期的效果,改变delta的值也不行,所以后面代码就不贴出来了,感兴趣的可以研究一下。


二、拉普拉斯变换:将拉普拉斯矩阵中的项与相应点的RGB值之积再乘以相应的系数的和作为当前点的RGB值。

例:用上面的例子,还是对E点进行锐化。

[java] view plaincopy
  1. // 拉普拉斯矩阵 
  2. int[] laplacian = new int[] { -1, -1, -1, -19, -1, -1, -1, -1 }; 
  3. float delta = 0.3;  
  4. E.r = A.r * laplacian[0] * delta + B.r * laplacian[1] * delta + C.r * laplacian[2] * delta + D.r * laplacian[3] * delta + E.r * laplacian[4] * delta + F.r * laplacian[5] * delta + G.r * laplacian[6] * delta + H.r * laplacian[7] * delta + I.r * laplacian[8] * delta; 
  5. // E.g和E.b值类似 
[java] view plaincopy
  1. // 拉普拉斯矩阵  
  2. int[] laplacian = new int[] { -1, -1, -1, -19, -1, -1, -1, -1 };  
  3. float delta = 0.3;   
  4. E.r = A.r * laplacian[0] * delta + B.r * laplacian[1] * delta + C.r * laplacian[2] * delta + D.r * laplacian[3] * delta + E.r * laplacian[4] * delta + F.r * laplacian[5] * delta + G.r * laplacian[6] * delta + H.r * laplacian[7] * delta + I.r * laplacian[8] * delta;  
  5. // E.g和E.b值类似  

下面看效果图:

原图:


处理后:


貌似处理有点问题,中间会看到很多的竖线,很明显,可能是没有优化好,因为采用了getPiexels() 和setPixels()方法,所以一维数组的对应图片的宽高有点麻烦。

下面贴代码,仅供参数,同样注意图片的大小,数组大小不能超过虚拟机规定值。

 

[java] view plaincopy
  1. /** 
  2.      * 图片锐化(拉普拉斯变换) 
  3.      * @param bmp 
  4.      * @return 
  5.      */  
  6.     private Bitmap sharpenImageAmeliorate(Bitmap bmp)  
  7.     {  
  8.         long start = System.currentTimeMillis();  
  9.         // 拉普拉斯矩阵  
  10.         int[] laplacian = new int[] { -1, -1, -1, -19, -1, -1, -1, -1 };  
  11.           
  12.         int width = bmp.getWidth();  
  13.         int height = bmp.getHeight();  
  14.         Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565);  
  15.           
  16.         int pixR = 0;  
  17.         int pixG = 0;  
  18.         int pixB = 0;  
  19.           
  20.         int pixColor = 0;  
  21.           
  22.         int newR = 0;  
  23.         int newG = 0;  
  24.         int newB = 0;  
  25.           
  26.         int idx = 0;  
  27.         float alpha = 0.3F;  
  28.         int[] pixels = new int[width * height];  
  29.         bmp.getPixels(pixels, 0, width, 00, width, height);  
  30.         for (int i = 1, length = height - 1; i < length; i++)  
  31.         {  
  32.             for (int k = 1, len = width - 1; k < len; k++)  
  33.             {  
  34.                 idx = 0;  
  35.                 for (int m = -1; m <= 1; m++)  
  36.                 {  
  37.                     for (int n = -1; n <= 1; n++)  
  38.                     {  
  39.                         pixColor = pixels[(i + n) * width + k + m];  
  40.                         pixR = Color.red(pixColor);  
  41.                         pixG = Color.green(pixColor);  
  42.                         pixB = Color.blue(pixColor);  
  43.                           
  44.                         newR = newR + (int) (pixR * laplacian[idx] * alpha);  
  45.                         newG = newG + (int) (pixG * laplacian[idx] * alpha);  
  46.                         newB = newB + (int) (pixB * laplacian[idx] * alpha);  
  47.                         idx++;  
  48.                     }  
  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.                 newR = 0;  
  57.                 newG = 0;  
  58.                 newB = 0;  
  59.             }  
  60.         }  
  61.           
  62.         bitmap.setPixels(pixels, 0, width, 00, width, height);  
  63.         long end = System.currentTimeMillis();  
  64.         Log.d("may""used time="+(end - start));  
  65.         return bitmap;  
  66.     }  




8、浮雕效果

这篇将讲到图片特效处理的浮雕效果。跟前面一样是对像素点进行处理,算法是通用的。

算法原理:用前一个像素点的RGB值分别减去当前像素点的RGB值并加上127作为当前像素点的RGB值。

例:

ABC

求B点的浮雕效果如下:

B.r = C.r - B.r + 127;

B.g = C.g - B.g + 127;

B.b = C.b - B.b + 127;

注意RGB值在0~255之间。

效果图:



                     原图                                                                              效果图



[java] view plaincopy
  1. package com.color;  
  2.   
  3. import android.content.Context;  
  4. import android.graphics.Bitmap;  
  5. import android.graphics.BitmapFactory;  
  6. import android.graphics.Canvas;  
  7. import android.graphics.Color;  
  8. import android.graphics.Paint;  
  9. import android.util.AttributeSet;  
  10. import android.widget.ImageView;  
  11.   
  12. public class ColorView extends ImageView {  
  13.   
  14.     private Paint myPaint = null;  
  15.     private Bitmap bitmap = null;  
  16.     private int width,height;  
  17.     private int[] oldPixels;    
  18.     private int[] newPixels;    
  19.     private int color,color2;  
  20.     private int pixelsR,pixelsG,pixelsB,pixelsA,pixelsR2,pixelsG2,pixelsB2;  
  21.       
  22.     public ColorView(Context context, AttributeSet attrs)  
  23.     {  
  24.         super(context, attrs);  
  25.         bitmap = BitmapFactory.decodeResource(context.getResources(),R.drawable.ww);   
  26.         width = bitmap.getWidth();    
  27.         height = bitmap.getHeight();  
  28.         oldPixels = new int[width*height];   
  29.         newPixels = new int[width*height];  
  30.         invalidate();  
  31.     }  
  32.     @Override  
  33.     protected void onDraw(Canvas canvas) {  
  34.         super.onDraw(canvas);   
  35.         //获取像素  
  36.         bitmap.getPixels(oldPixels, 0, width, 00, width, height);  
  37.           
  38.         for(int i = 1;i < height*width; i++){  
  39.                 color = oldPixels[i-1];  
  40.                 //前一个像素  
  41.                 pixelsR = Color.red(color);  
  42.                 pixelsG = Color.green(color);  
  43.                 pixelsB = Color.blue(color);  
  44.                 //当前像素  
  45.                 color2 = oldPixels[i];  
  46.                 pixelsR2 = Color.red(color2);  
  47.                 pixelsG2 = Color.green(color2);  
  48.                 pixelsB2 = Color.blue(color2);  
  49.                   
  50.                 pixelsR = (pixelsR - pixelsR2 + 127);  
  51.                 pixelsG = (pixelsG - pixelsG2 + 127);  
  52.                 pixelsB = (pixelsB - pixelsB2 + 127);  
  53.                 //均小于等于255  
  54.                 if(pixelsR > 255){  
  55.                     pixelsR = 255;  
  56.                 }  
  57.                   
  58.                 if(pixelsG > 255){  
  59.                     pixelsG = 255;  
  60.                 }  
  61.                   
  62.                 if(pixelsB > 255){  
  63.                     pixelsB = 255;  
  64.                 }  
  65.                   
  66.                 newPixels[i] = Color.argb(pixelsA, pixelsR, pixelsG, pixelsB);  
  67.                   
  68.         }  
  69.         bitmap.setPixels(newPixels, 0, width, 00, width, height);  
  70.         canvas.drawBitmap(bitmap,0,0,myPaint);  
  71.     }  
  72. }  


9、底片效果


这篇将讲到图片特效处理的底片效果。跟前面一样是对像素点进行处理,算法是通用的。

算法原理:将当前像素点的RGB值分别与255之差后的值作为当前点的RGB值。

例:

ABC

求B点的底片效果:

B.r = 255 - B.r;

B.g = 255 - B.g;

B.b = 255 - B.b;

效果图:


                     效果图                                                                     原图

代码:

 

[java] view plaincopy
  1. package com.color;  
  2.   
  3. import android.content.Context;  
  4. import android.graphics.Bitmap;  
  5. import android.graphics.BitmapFactory;  
  6. import android.graphics.Canvas;  
  7. import android.graphics.Color;  
  8. import android.graphics.Paint;  
  9. import android.util.AttributeSet;  
  10. import android.widget.ImageView;  
  11.   
  12. public class ColorView extends ImageView {  
  13.   
  14.     private Paint myPaint = null;  
  15.     private Bitmap bitmap = null;  
  16.     private int width,height;  
  17.     private int[] oldPixels;    
  18.     private int[] newPixels;    
  19.     private int color,color2;  
  20.     private int pixelsR,pixelsG,pixelsB,pixelsA,pixelsR2,pixelsG2,pixelsB2;  
  21.       
  22.     public ColorView(Context context, AttributeSet attrs)  
  23.     {  
  24.         super(context, attrs);  
  25.         bitmap = BitmapFactory.decodeResource(context.getResources(),R.drawable.ww);   
  26.         width = bitmap.getWidth();    
  27.         height = bitmap.getHeight();  
  28.         oldPixels = new int[width*height];   
  29.         newPixels = new int[width*height];  
  30.         invalidate();  
  31.     }  
  32.     @Override  
  33.     protected void onDraw(Canvas canvas) {  
  34.         super.onDraw(canvas);   
  35.         //获取像素  
  36.         bitmap.getPixels(oldPixels, 0, width, 00, width, height);  
  37.           
  38.         for(int i = 1;i < height*width; i++){  
  39.                 color = oldPixels[i];  
  40.                 //获取RGB分量  
  41.                 pixelsA = Color.alpha(color);  
  42.                 pixelsR = Color.red(color);  
  43.                 pixelsG = Color.green(color);  
  44.                 pixelsB = Color.blue(color);  
  45.                   
  46.                 //转换  
  47.                 pixelsR = (255 - pixelsR);  
  48.                 pixelsG = (255 - pixelsG);  
  49.                 pixelsB = (255 - pixelsB);  
  50.                 //均小于等于255大于等于0  
  51.                 if(pixelsR > 255){  
  52.                     pixelsR = 255;  
  53.                 }  
  54.                 else if(pixelsR < 0){  
  55.                     pixelsR = 0;  
  56.                 }  
  57.                 if(pixelsG > 255){  
  58.                     pixelsG = 255;  
  59.                 }  
  60.                 else if(pixelsG < 0){   
  61.                     pixelsG = 0;  
  62.                 }  
  63.                 if(pixelsB > 255){  
  64.                     pixelsB = 255;  
  65.                 }  
  66.                 else if(pixelsB < 0){  
  67.                     pixelsB = 0;  
  68.                 }  
  69.                 //根据新的RGB生成新像素  
  70.                 newPixels[i] = Color.argb(pixelsA, pixelsR, pixelsG, pixelsB);  
  71.                   
  72.         }  
  73.         //根据新像素生成新图片  
  74.         bitmap.setPixels(newPixels, 0, width, 00, width, height);  
  75.         canvas.drawBitmap(bitmap,0,0,myPaint);  
  76.     }  
  77. }  


9、熔铸特效


代码:

[java] view plaincopy
  1. package com.color;  
  2.   
  3. import android.content.Context;  
  4. import android.graphics.Bitmap;  
  5. import android.graphics.BitmapFactory;  
  6. import android.graphics.Canvas;  
  7. import android.graphics.Color;  
  8. import android.graphics.Paint;  
  9. import android.util.AttributeSet;  
  10. import android.widget.ImageView;  
  11.   
  12. public class ColorView extends ImageView {  
  13.   
  14.     private Paint myPaint = null;  
  15.     private Bitmap bitmap = null;  
  16.     private int width, height;  
  17.     private int[] oldPixels;  
  18.     private int[] newPixels;  
  19.     private int color, color2;  
  20.     private int pixelsR, pixelsG, pixelsB, pixelsA, pixelsR2, pixelsG2,  
  21.             pixelsB2;  
  22.   
  23.     public ColorView(Context context, AttributeSet attrs) {  
  24.         super(context, attrs);  
  25.         bitmap = BitmapFactory.decodeResource(context.getResources(),  
  26.                 R.drawable.ww);  
  27.         width = bitmap.getWidth();  
  28.         height = bitmap.getHeight();  
  29.         oldPixels = new int[width * height];  
  30.         newPixels = new int[width * height];  
  31.         invalidate();  
  32.     }  
  33.   
  34.     @Override  
  35.     protected void onDraw(Canvas canvas) {  
  36.         super.onDraw(canvas);  
  37.         // 获取像素  
  38.         bitmap.getPixels(oldPixels, 0, width, 00, width, height);  
  39.   
  40.         for (int i = 1; i < height * width; i++) {  
  41.             color = oldPixels[i];  
  42.             // 获取RGB分量  
  43.             pixelsA = Color.alpha(color);  
  44.             pixelsR = Color.red(color);  
  45.             pixelsG = Color.green(color);  
  46.             pixelsB = Color.blue(color);  
  47.             //R  
  48.             int pixel = pixelsR * 128 / (pixelsG + pixelsB + 1);  
  49.             if (pixel < 0) {  
  50.                 pixel = 0;  
  51.             } else if (pixel > 255) {  
  52.                 pixel = 255;  
  53.             }  
  54.             pixelsR = pixel;  
  55.             //G  
  56.             pixel = pixelsG * 128 / (pixelsB + pixelsR + 1);  
  57.             if (pixel < 0){  
  58.                 pixel = 0;  
  59.             }  
  60.             else if (pixel > 255){  
  61.                 pixel = 255;  
  62.             }  
  63.             pixelsG = pixel;  
  64.             //B  
  65.             pixel = pixelsB * 128 / (pixelsR + pixelsG + 1);  
  66.             if (pixel < 0){  
  67.                 pixel = 0;  
  68.             }  
  69.             else if (pixel > 255){  
  70.                 pixel = 255;  
  71.             }  
  72.             pixelsB = pixel;  
  73.   
  74.             // 根据新的RGB生成新像素  
  75.             newPixels[i] = Color.argb(pixelsA, pixelsR, pixelsG, pixelsB);  
  76.   
  77.         }  
  78.         // 根据新像素生成新图片  
  79.         bitmap.setPixels(newPixels, 0, width, 00, width, height);  
  80.         canvas.drawBitmap(bitmap, 00, myPaint);  
  81.     }  
  82. }  


10、冰冻效果

                    原图                                                                          效果图



代码:

[cpp] view plaincopy
  1. package com.color;  
  2.   
  3. import android.content.Context;  
  4. import android.graphics.Bitmap;  
  5. import android.graphics.BitmapFactory;  
  6. import android.graphics.Canvas;  
  7. import android.graphics.Color;  
  8. import android.graphics.Paint;  
  9. import android.util.AttributeSet;  
  10. import android.widget.ImageView;  
  11.   
  12. public class ColorView extends ImageView {  
  13.   
  14.     private Paint myPaint = null;  
  15.     private Bitmap bitmap = null;  
  16.     private int width, height;  
  17.     private int[] oldPixels;  
  18.     private int[] newPixels;  
  19.     private int color, color2;  
  20.     private int pixelsR, pixelsG, pixelsB, pixelsA, pixelsR2, pixelsG2,  
  21.             pixelsB2;  
  22.   
  23.     public ColorView(Context context, AttributeSet attrs) {  
  24.         super(context, attrs);  
  25.         bitmap = BitmapFactory.decodeResource(context.getResources(),  
  26.                 R.drawable.ww);  
  27.         width = bitmap.getWidth();  
  28.         height = bitmap.getHeight();  
  29.         oldPixels = new int[width * height];  
  30.         newPixels = new int[width * height];  
  31.         invalidate();  
  32.     }  
  33.   
  34.     @Override  
  35.     protected void onDraw(Canvas canvas) {  
  36.         super.onDraw(canvas);  
  37.         // 获取像素  
  38.         bitmap.getPixels(oldPixels, 0, width, 0, 0, width, height);  
  39.   
  40.         for (int i = 1; i < height * width; i++) {  
  41.             color = oldPixels[i];  
  42.             // 获取RGB分量  
  43.             pixelsA = Color.alpha(color);  
  44.             pixelsR = Color.red(color);  
  45.             pixelsG = Color.green(color);  
  46.             pixelsB = Color.blue(color);  
  47.             //R  
  48.             int pixel = pixelsR - pixelsG - pixelsB;  
  49.             pixel = pixel * 3 / 2;  
  50.             if (pixel < 0) {  
  51.                 pixel = -pixel;  
  52.             }  
  53.             if (pixel > 255){  
  54.                 pixel = 255;  
  55.             }  
  56.             pixelsR = pixel; // 计算后重置R值,以下类同  
  57.             //G  
  58.             pixel = pixelsG - pixelsR - pixelsB;  
  59.             pixel = pixel * 3 / 2;  
  60.             if (pixel < 0) {  
  61.                 pixel = -pixel;  
  62.             }  
  63.             if (pixel > 255){  
  64.                 pixel = 255;  
  65.             }  
  66.             pixelsG = pixel;  
  67.             //B  
  68.             pixel = pixelsB - pixelsR - pixelsG;  
  69.             pixel = pixel * 3 / 2;  
  70.             if (pixel < 0) {  
  71.                 pixel = -pixel;  
  72.             }  
  73.             if (pixel > 255){  
  74.                 pixel = 255;  
  75.             }  
  76.             pixelsB = pixel;  
  77.               
  78.             // 根据新的RGB生成新像素  
  79.             newPixels[i] = Color.argb(pixelsA, pixelsR, pixelsG, pixelsB);  
  80.   
  81.         }  
  82.         // 根据新像素生成新图片  
  83.         bitmap.setPixels(newPixels, 0, width, 0, 0, width, height);  
  84.         canvas.drawBitmap(bitmap, 0, 0, myPaint);  
  85.     }  
  86. }  


11、图片叠加

这篇将讲到图片特效处理的图片叠加效果。叠加原理是两张图片的像素点按透明度叠加,不会进行颜色过滤。叠加图片可以是JPG格式,跟前在一样,最好是放大assets目录。下面看效果图:

+

代码:

[java] view plaincopy
  1. /** 
  2.      * 图片效果叠加 
  3.      * @param bmp 限制了尺寸大小的Bitmap 
  4.      * @return 
  5.      */  
  6.     private Bitmap overlay(Bitmap bmp)  
  7.     {  
  8.         long start = System.currentTimeMillis();  
  9.         int width = bmp.getWidth();  
  10.         int height = bmp.getHeight();  
  11.         Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565);  
  12.           
  13.         // 对边框图片进行缩放  
  14.         Bitmap overlay = BitmapFactory.decodeResource(mContext.getResources(), R.drawable.rainbow_overlay);  
  15.         int w = overlay.getWidth();  
  16.         int h = overlay.getHeight();  
  17.         float scaleX = width * 1F / w;  
  18.         float scaleY = height * 1F / h;  
  19.         Matrix matrix = new Matrix();  
  20.         matrix.postScale(scaleX, scaleY);  
  21.           
  22.         Bitmap overlayCopy = Bitmap.createBitmap(overlay, 00, w, h, matrix, true);  
  23.           
  24.         int pixColor = 0;  
  25.         int layColor = 0;  
  26.           
  27.         int pixR = 0;  
  28.         int pixG = 0;  
  29.         int pixB = 0;  
  30.         int pixA = 0;  
  31.           
  32.         int newR = 0;  
  33.         int newG = 0;  
  34.         int newB = 0;  
  35.         int newA = 0;  
  36.           
  37.         int layR = 0;  
  38.         int layG = 0;  
  39.         int layB = 0;  
  40.         int layA = 0;  
  41.           
  42.         final float alpha = 0.5F;  
  43.           
  44.         int[] srcPixels = new int[width * height];  
  45.         int[] layPixels = new int[width * height];  
  46.         bmp.getPixels(srcPixels, 0, width, 00, width, height);  
  47.         overlayCopy.getPixels(layPixels, 0, width, 00, width, height);  
  48.           
  49.         int pos = 0;  
  50.         for (int i = 0; i < height; i++)  
  51.         {  
  52.             for (int k = 0; k < width; k++)  
  53.             {  
  54.                 pos = i * width + k;  
  55.                 pixColor = srcPixels[pos];  
  56.                 layColor = layPixels[pos];  
  57.                   
  58.                 pixR = Color.red(pixColor);  
  59.                 pixG = Color.green(pixColor);  
  60.                 pixB = Color.blue(pixColor);  
  61.                 pixA = Color.alpha(pixColor);  
  62.                   
  63.                 layR = Color.red(layColor);  
  64.                 layG = Color.green(layColor);  
  65.                 layB = Color.blue(layColor);  
  66.                 layA = Color.alpha(layColor);  
  67.                   
  68.                 newR = (int) (pixR * alpha + layR * (1 - alpha));  
  69.                 newG = (int) (pixG * alpha + layG * (1 - alpha));  
  70.                 newB = (int) (pixB * alpha + layB * (1 - alpha));  
  71.                 layA = (int) (pixA * alpha + layA * (1 - alpha));  
  72.                   
  73.                 newR = Math.min(255, Math.max(0, newR));  
  74.                 newG = Math.min(255, Math.max(0, newG));  
  75.                 newB = Math.min(255, Math.max(0, newB));  
  76.                 newA = Math.min(255, Math.max(0, layA));  
  77.                   
  78.                 srcPixels[pos] = Color.argb(newA, newR, newG, newB);  
  79.             }  
  80.         }  
  81.           
  82.         bitmap.setPixels(srcPixels, 0, width, 00, width, height);  
  83.         long end = System.currentTimeMillis();  
  84.         Log.d("may""overlayAmeliorate used time="+(end - start));  
  85.         return bitmap;  
  86.     }  


叠加的边框图片还是大点比较好,也要控制被叠加图片大小。alpha变量值可以根据需求修改,建议还是大于0.5比较好,不然原图会看不清楚。



12 、怀旧效果

图片特效处理系列将介绍图片的像素点的特效处理,这些物资注重的是原理。也就是说只要你知道这些算法不管是C++,VB,C#,JAVA都可以做出相同的特效。下面将介绍图片怀旧效果的算法。算法如下:


上面公式的意思是说将每个像素点的RGB值先分离出来,然后再按照上面的三个算式分别重新计算出RGB值然后做为当前点的RGB值。

下面看效果图片:

原图片:


处理后:



代码:

 

[java] view plaincopy
  1. /** 
  2.      * 怀旧效果(相对之前做了优化快一倍) 
  3.      * @param bmp 
  4.      * @return 
  5.      */  
  6.     private Bitmap oldRemeber(Bitmap bmp)  
  7.     {  
  8.         // 速度测试  
  9.         long start = System.currentTimeMillis();  
  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, 00, 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 ? 255 : newR, newG > 255 ? 255 : newG, newB > 255 ? 255 : newB);  
  34.                 pixels[width * i + k] = newColor;  
  35.             }  
  36.         }  
  37.           
  38.         bitmap.setPixels(pixels, 0, width, 00, width, height);  
  39.         long end = System.currentTimeMillis();  
  40.         Log.d("may""used time="+(end - start));  
  41.         return bitmap;  
  42.     }  


上面的代码是优化了的,也就是用到了这篇android图像处理系列之六--给图片添加边框(下)-图片叠加里面所说的getPixels()和setPixels()。自己简单的测试了一下,速度比原来getPixel()和setPixel()速度快了一倍。



0 0