涉及到的内容:

1)File读取本地文件;

2)用ArrayList容器装文件的名称和路径数据,并用一个ArrayAdapter讲数据显示在一个ListView控件上;

3)给ListView控件加OnItemclick点击事件,获取点击的图片的路径;

4)根据图片路径,用FileInputStream ,以流的方式将本地图片读到程序;

5)用Bitmap的BitmapFactory.decodeStream(流)将图片变成位图

6)用画图工具类将读进来的原图片和水印图片画到同一张图上,并且显示到Imageview控件上。

7)完成。

代码:

1)列出文件显示的类

package       com.yimo      ;      

import       java.io.File      ;      
import       java.util.ArrayList      ;      
import       java.util.List      ;      

import       android.app.ListActivity      ;      
import       android.content.Intent      ;      
import       android.os.Bundle      ;      
import       android.view.View      ;      
import       android.widget.ArrayAdapter      ;      
import       android.widget.ListView      ;      
import       android.widget.TextView      ;      

public       class FileManagerActivity       extends ListActivity       {      
/***
 * 文件管理器,用来列出本地的所有文件
 * 1,选取要加水印的图片
 * 2,放一张水印图片
 * 3,将原图片画进一张画布,并且把水印画上去
 * @author lanyimo
 */      
private TextView mPath      ;      //这个就在列表上面,显示当前文件的路径      
private       List items      =      null      ;      //存放文件的名称      
private       List paths      =      null      ;      //存放文件的路径      
private       String rootPath      =      "/"      ;      
 @Override      
public       void onCreate      (Bundle savedInstanceState      )       {      
super.      onCreate      (savedInstanceState      )      ;      
 setContentView      (R.      layout.      file_list      )      ;      
 mPath      =      (TextView      ) findViewById      (R.      id.      mPath      )      ;      
 getFileDir      (rootPath      )      ;      
}      

private       void getFileDir      (      String filePath      )      {      
 mPath.      setText      (      "文件路径:"      +filePath      )      ;      
 mPath.      setTextSize      (20f      )      ;      

/**实例化两个list*******/      
 items      =      new       ArrayList      (      )      ;      
 paths      =      new       ArrayList      (      )      ;      
File f      =      new       File      (filePath      )      ;      
File       [      ] files      =f.      listFiles      (      )      ;      
//判断文件路径是否为根目录      
if      (      !filePath.      equals      (rootPath      )      )      {      

//list的第一行加一个选项,跳转到根目录----------      
 items.      add      (      "go back to"      +rootPath      )      ;      
 paths.      add      (rootPath      )      ;      
//跳转到上级目录      
 items.      add      (      "go back to ...../"      )      ;      
 paths.      add      (f.      getParent      (      )      )      ;      //-------------------      

}      
/**将文件名和文件路径放到list容器中***/      
for       (      int i       =       0      ; i       <      ; files.      length      ; i      ++      )       {      
File file      =files      [i      ]      ;      
 items.      add      (file.      getName      (      )      )      ;      
 paths.      add      (file.      getPath      (      )      )      ;      
}      
//用适配器讲数据加到listView上显示      
 ArrayAdapter fileList      =      new ArrayAdapter      (getApplication      (      ), R.      layout.      file_rows,items      )      ;      
 setListAdapter      (fileList      )      ;      

}      
 @Override      
protected       void onListItemClick      (      ListView l,       View v,       int position,       long id      )       {      
File file      =      new       File      (paths.      get      (position      )      )      ;      
if      (file.      isDirectory      (      )      )      {      
//如果是文件夹,继续调用getFIleDir()方法打开,否则弹出对话框一枚      
 getFileDir      (paths.      get      (position      )      )      ;      
}      else      {      
 Intent intent      =      new Intent      (      )      ;      
 intent.      setClass      (getApplication      (      ),testGetFile.      class      )      ;      
 Bundle bundle      =      new Bundle      (      )      ;      
 bundle.      putString      (      "test", paths.      get      (position      )      )      ;      
 intent.      putExtras      (bundle      )      ;      
 startActivity      (intent      )      ;      
}      
}      

}

带加水印方法的类:



package       com.yimo      ;      

import       java.io.File      ;      
import       java.io.FileInputStream      ;      
import       java.io.IOException      ;      

import       android.app.Activity      ;      
import       android.graphics.Bitmap      ;      
import       android.graphics.BitmapFactory      ;      
import       android.graphics.Canvas      ;      
import       android.graphics.Bitmap.Config      ;      
import       android.net.Uri      ;      
import       android.os.Bundle      ;      
import       android.os.Environment      ;      
import       android.util.Log      ;      
import       android.view.View      ;      
import       android.view.View.OnClickListener      ;      
import       android.widget.Button      ;      
import       android.widget.ImageView      ;      

public       class testGetFile       extends Activity      {      
/***
 * 文件上传及给上传的图片加水印、
 */      

 @Override      
protected       void onCreate      (Bundle savedInstanceState      )       {      
super.      onCreate      (savedInstanceState      )      ;      
 setContentView      (R.      layout.      file_image      )      ;      
Button btn      =      (      Button      ) findViewById      (R.      id.      test_btn      )      ;      
 btn.      setOnClickListener      (      new OnClickListener      (      )       {      
 @Override      
public       void onClick      (      View v      )       {      
try       {      
 ImageView img      =      (ImageView      ) findViewById      (R.      id.      test_img_file      )      ;      
//获取从本地获取的文件路径,用FileInputstream读入文件,并将图片文件转换成位图      
 Bundle bundle      =getIntent      (      ).      getExtras      (      )      ;      
String path      =bundle.      getString      (      "test"      )      ;      
FileInputStream fa      =      new       FileInputStream      (path      )      ;      
 Bitmap bm      =BitmapFactory.      decodeStream      (fa      )      ;      //原图      
 Bitmap wm      =BitmapFactory.      decodeResource      (getResources      (      ), R.      drawable.      wate_market      )      ;      //水印      
//将creatBitmap()方法的返回值(返回位图)放到图片控件显示      
 img.      setImageBitmap      (createBitMap      (bm,wm      )      )      ;      
}       catch       (      IOException e      )       {      
 e.      printStackTrace      (      )      ;      
}      
}      
}      )      ;      
}      
private Bitmap createBitMap      (Bitmap src,Bitmap wmsrc      )      {      
/**
 * 水印制作方法
 */      
String tag      =      "xx"      ;      
 Log.      d      (tag,       "开始了,画图"      )      ;      
if      (src      ==      null      )      {      
return       null      ;      
}      
int w      =src.      getWidth      (      )      ;      
int h      =src.      getHeight      (      )      ;      
int wmw      =wmsrc.      getWidth      (      )      ;      
int wmh      =wmsrc.      getHeight      (      )      ;      
//create the new bitmap      
 Bitmap newb      =Bitmap.      createBitmap      (w,h,Config.      ARGB_8888      )      ;      //创建一个底图      
Canvas cv      =      new       Canvas      (newb      )      ;      
//将底图画进去      
 cv.      drawBitmap      (src,       0,       0,      null      )      ;      //在0,0坐标开始画入src      
//讲水印画进去      
 cv.      drawBitmap      (wmsrc, w      -wmw      +      5, h      -wmh      +      5,       null      )      ;      
//保存图片      
 cv.      save      (      Canvas.      ALL_SAVE_FLAG      )      ;      
 cv.      restore      (      )      ;      
return newb      ;      

}      
}

另外,xml布局文件2个;

一个带listView的布局,如果你java文件中的文件管理那个类继承自ListActivity,请在布局文件中的listView控件加id为@android/id/list,如果继承自Activity,就不用,普通方式写id就行。

一个是图像显示的布局,就一个按钮和一个Imageview控件在里面。

图片涂鸦,水印-图片叠加


图片涂鸦和水印其实是一个功能,实现的方式是一样的,就是一张大图片和一张小点图片叠加即可。前面在 android图像处理系列之六--给图片添加边框(下)-图片叠加 中也讲到了图



图片涂鸦和水印其实是一个功能,实现的方式是一样的,就是一张大图片和一张小点图片叠加即可。前面在android图像处理系列之六--给图片添加边框(下)-图片叠加中也讲到了图片叠加,里面实现的原理是直接操作像素点。下面给出别外一种方式让图片叠加--用Canvas处理图片,canvas已经封装好了,直接调用就行。

下面看效果:

 


+


=


 

代码:

 





1. /**
2.      * 组合涂鸦图片和源图片
3.      * @param src 源图片
4.      * @param watermark 涂鸦图片
5.      * @return
6.      */  
7. public Bitmap doodle(Bitmap src, Bitmap watermark)  
8.     {  
9. // 另外创建一张图片  
10. // 创建一个新的和SRC长度宽度一样的位图  
11. new Canvas(newb);  
12. 0, 0, null);// 在 0,0坐标开始画入原图片src  
13. 2, (src.getHeight() - watermark.getHeight()) / 2, null); // 涂鸦图片画到原图片中间位置  
14.         canvas.save(Canvas.ALL_SAVE_FLAG);  
15.         canvas.restore();  
16.           
17.         watermark.recycle();  
18. null;  
19.           
20. return newb;  
21.     }




跟前面一样,要注意图片最好放在assets目录,另外注意图片回收,不然图片过到会造成内存紧张。这种叠加方式一般选用PNG格式的图片做为涂鸦图片或者水印,当然也可以用JPG,那就需要按照前面所说的 android图像处理系列之六--给图片添加边框(下)-图片叠加

进行像素点过滤,这样会影响处理速度,所以不建议用JPG图片,如果能写更高效的算法,也可以。


另外在做涂鸦的时候,需求可能会是用户可以按住涂鸦图片,然后进行拖动效果。这样的话,我给个思路,重写ImageView里面的onTouchEvent方法,MotionEvent.getAction()里面有三种状态,MotionEvent.ACTION_DOWN、MotionEvent.ACTION_UP和MotionEvent.ACTION_MOVE,根据这三种状态来判断用户的行为,决定是否移动图片,另外要注意判断涂鸦图片是否移动到原图片的边缘。由于这部分代码是跟裁剪放在一样的,不好贴出来,所以给大家一个思路,后面会把裁剪的代码贴出来。


android 给图片加水印


public static void watermark(String filename) {
try {
String watermark=FilepathConstants.CASEATTACHMENT + File.separator + "watermark.png";
BitmapFactory.Options oldOpts = new BitmapFactory.Options();
oldOpts.inSampleSize = 4;
oldOpts.inJustDecodeBounds = false;
Bitmap oriBmp = BitmapFactory.decodeFile(filename,oldOpts);
Bitmap rs=doodle(oriBmp,makeTextBitMap());
File destFile = new File(filename);
destFile.createNewFile();
OutputStream os = new FileOutputStream(destFile);
// 存储
rs.compress(CompressFormat.JPEG, 100, os);
// 关闭流
os.close();
} catch (Exception e) {
Log.d("watermark", "水印错误");
}
}
 
/**
    * 组合图片和源图片
    * @param src 源图片
    * @param watermark 涂鸦图片
    * @return
   */
   public static  Bitmap doodle(Bitmap src, Bitmap watermark)
   {
       // 另外创建一张图片
       Bitmap newb = Bitmap.createBitmap(src.getWidth(), src.getHeight(), Config.ARGB_8888);// 创建一个新的和SRC长度宽度一样的位图
       Canvas canvas = new Canvas(newb);
       canvas.drawBitmap(src, 0, 0, null);// 在 0,0坐标开始画入原图片src
       //canvas.drawBitmap(watermark, (src.getWidth() - watermark.getWidth()) / 2, (src.getHeight() - watermark.getHeight()) / 2, null); // 涂鸦图片画到原图片中间位置
 
       canvas.drawBitmap( watermark, src.getWidth() - watermark.getWidth() + 5, src.getHeight() - watermark.getHeight() + 5, null );//在src的右下角画入水印
 
       canvas.save(Canvas.ALL_SAVE_FLAG);
       canvas.restore();
 
       watermark.recycle();
       watermark = null;
 
      return newb;
   }
 
   public static Bitmap makeTextBitMap(){
   int w = 360,h = 140;

   String mstrTitle =“这里是你要加的水印文字这里是你要加的水印文字这里是你要加的水印文字这里是你要加的水印文字这里是你要加的水印文字这里是你要加的水印文字”;

;
   Bitmap mbmpTest = Bitmap.createBitmap(w,h, Config.ARGB_8888);
   Canvas canvasTemp = new Canvas(mbmpTest);
   canvasTemp.drawColor(Color.TRANSPARENT);
   Paint p = new Paint();
   String familyName = "宋体";
   Typeface font = Typeface.create(familyName,Typeface.BOLD);
   p.setColor(Color.RED);
   p.setTypeface(font);
   p.setTextSize(22);
   canvasTemp.drawText(mstrTitle,0,100,p);
   return mbmpTest;
 
   }


android 实现图片加水印



File fImage = new File("/sdcard/dcim","beijing.jpeg");

FileOutputStream iStream = new FileOutputStream(fImage); 

* 取出Bitmap oriBmp

oriBmp.compress(CompressFormat.JPEG, 100, iStream);


int w = 320,h = 240;
String mstrTitle = “感受Android带给我们的新体验”;
Bitmap mbmpTest = Bitmap.createBitmap(w,h, Config.ARGB_8888);
Canvas canvasTemp = new Canvas(mbmpTest);
canvasTemp.drawColor(Color.WHITE);
Paint p = new Paint();
String familyName = “宋体”;
Typeface font = Typeface.create(familyName,Typeface.BOLD);
p.setColor(Color.RED);
p.setTypeface(font);
p.setTextSize(22);
canvasTemp.drawText(mstrTitle,0,100,p);

6.图片水印的生成方法

  生成水印的过程。其实分为三个环节:第一,载入原始图片;第二,载入水印图片;第三,保存新的图片。

  /**

  * create the bitmap from a byte array

  *

  * @param src the bitmap object you want proecss

  * @param watermark the water mark above the src

  * @return return a bitmap object ,if paramter's length is 0,return null

  */

  private Bitmap createBitmap( Bitmap src, Bitmap watermark )

  {

  String tag = "createBitmap";

  Log.d( tag, "create a new bitmap" );

  if( src == null )

  {

  return null;

  }

  int w = src.getWidth();

  int h = src.getHeight();

  int ww = watermark.getWidth();

  int wh = watermark.getHeight();

  //create the new blank bitmap

  Bitmap newb = Bitmap.createBitmap( w, h, Config.ARGB_8888 );//创建一个新的和SRC长度宽度一样的位图

  Canvas cv = new Canvas( newb );

  //draw src into

  cv.drawBitmap( src, 0, 0, null );//在 0,0坐标开始画入src

  //draw watermark into

  cv.drawBitmap( watermark, w - ww + 5, h - wh + 5, null );//在src的右下角画入水印

  //save all clip

  cv.save( Canvas.ALL_SAVE_FLAG );//保存

  //store

 cv.restore();//存储

  return newb;

  }




 

//根据我自己的需要改进了一下



按 Ctrl+C 复制代码

//获取图片缩小的图片
    public static Bitmap scaleBitmap(String src,int max)
    {
        //获取图片的高和宽
        BitmapFactory.Options options = new BitmapFactory.Options();
        //这一个设置使 BitmapFactory.decodeFile获得的图片是空的,但是会将图片信息写到options中
        options.inJustDecodeBounds = true;        
        BitmapFactory.decodeFile(src, options); 
       // 计算比例 为了提高精度,本来是要640 这里缩为64
        max=max/10;
        int be = options.outWidth / max;
         if(be%10 !=0)
          be+=10;
         be=be/10;
         if (be <= 0)
          be = 1;
        options.inSampleSize = be;
        //设置可以获取数据
        options.inJustDecodeBounds = false;
        //获取图片
        return BitmapFactory.decodeFile(src, options);        
    }
    // 加水印 也可以加文字
    public static Bitmap watermarkBitmap(Bitmap src, Bitmap watermark,
            String title) {
        if (src == null) {
            return null;
        }
        int w = src.getWidth();
        int h = src.getHeight(); 
        //需要处理图片太大造成的内存超过的问题,这里我的图片很小所以不写相应代码了        
        Bitmap newb= Bitmap.createBitmap(w, h, Config.ARGB_8888);// 创建一个新的和SRC长度宽度一样的位图
        Canvas cv = new Canvas(newb);
        cv.drawBitmap(src, 0, 0, null);// 在 0,0坐标开始画入src    
        Paint paint=new Paint();
        //加入图片
        if (watermark != null) {
            int ww = watermark.getWidth();
            int wh = watermark.getHeight();
            paint.setAlpha(50);
            cv.drawBitmap(watermark, w - ww + 5, h - wh + 5, paint);// 在src的右下角画入水印            
        }
        //加入文字
        if(title!=null)
        {
            String familyName ="宋体";
            Typeface font = Typeface.create(familyName,Typeface.BOLD);            
            TextPaint textPaint=new TextPaint();
            textPaint.setColor(Color.RED);
            textPaint.setTypeface(font);
            textPaint.setTextSize(22);
            //这里是自动换行的
            StaticLayout layout = new StaticLayout(title,textPaint,w,Alignment.ALIGN_NORMAL,1.0F,0.0F,true);
            layout.draw(cv);
            //文字就加左上角算了
            //cv.drawText(title,0,40,paint); 
        }
        cv.save(Canvas.ALL_SAVE_FLAG);// 保存
        cv.restore();// 存储
        return newb;
    }

按 Ctrl+C 复制代码