网络图片框架

网络图片框架

  1. 大图片的处理原理
  2. ImageView(原生)
  3. SmartImageView(废弃)
  4. Glide(Google)
  5. Picasso(Square)
  6. Fresco(FaceBooK)
  7. Universal ImageLoader(UIL)
01-图片的处理原理
  1. 安卓中图片支持的像素点: (jpg,png,webp)
    Config.ARGB_4444 =16bit = 2byte
    Config.ARGB_8888 =32bit = 4byte(默认)
    Config.RGB_565 = 16bit = 2byte
  2. 大图片的加载 设置图片的压缩比例读取
    • 位图类的作用:对于大图片他都会等比例的缩放到ImageView中 与在选项中属性中的比例设置无关,
    • 总结:只要图片的大小大于手机的分辨率,那么ImageView加载位图后都会等比例的缩放后适配在手机屏幕中 1.如果直接读取会报ooM异常,如果在位图设置选项比例后读取的方法后读取就不回会报异常,异常位图中设置的 比例与显示在屏幕中的比例无关,因为位图会自动适配加载到ImageView中,

//代码步骤
  1. 获取图片的元数据中的宽width和高height
  2. 然后再获取ImageView控件的宽和高 iv_width 和 iv_height
  3. 分别计算宽和高应该缩放的倍率,然后取最大值Math.max(widht/iv_width,height/iv_height) = smpleSize(缩放比例);
  4. 将jpg转换为Bitmap的时候,将sampleSize作为参数传入进去,让API去缩放.得到一个缩放后的bitmap
  5. 将缩放后的bitmap显示到ImageView   

<ImageView 
        android:layout_width="match_parent"
        android:layout_height="match_parent"  //下面需要获得该控件的长度.
        android:id="@+id/iv"
        />

public class MainActivity extends Activity {
  private ImageView iv;
  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    iv = (ImageView) findViewById(R.id.iv);
    //下面可以在onCreate的中可以获得控件的长度
    //iv.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListen() {
    //@Override
    //public void onGlobalLayout() {
    //      int iv_height = iv.getHeight();
    //      int iv_width = iv.getWidth();
    //  }
    //});
    //注意此处的因为在OnCreate()的绘制View,在这里不能够获得控件的长度.
    int iv_height = iv.getHeight();
    int iv_width = iv.getWidth();
    Log.d("tag", "iv_height="+iv_height+"/iv_width="+iv_width);
  }

  public void load(View view){
    //最普通的方式(不对图片进行等比例缩放时)加载图片的两行核心代码
    //Bitmap bitmap = BitmapFactory.decodeFile("/mnt/sdcard/dog.jpg");
    //iv.setImageBitmap(bitmap);

    File file = new File(Environment.getExternalStorageDirectory(),"me.jpg");
    //先将jpg或者png转换为Bitmap,然后将Bitmap设置给ImageView即可

    Options opts = new Options();
    //告诉bitmapFactory仅仅去获取图片的元数据(宽高),而不是去加载整个图片
    opts.inJustDecodeBounds = true;
    //1. 获取图片的元数据中的宽width和高height
    //如果传入了opts.inJustDecodeBounds = true的opts,那么该方法的返回值就为null
    //该方法将获取到的结果又保存到了opts对象上,此时的返回值是null
    BitmapFactory.decodeFile(file.getAbsolutePath(), opts);
    int width = opts.outWidth;
    int height = opts.outHeight;

    //2. 然后再获取ImageView控件的宽和高 iv_width 和 iv_height
    /*
     * 注意:imageView的宽和高写的是match_parent才能获取到,如果是wrap则拿到的是0
     * 注意: 获取控件的尺寸信息,一定要等界面完全绘制完了再去拿,不要再onCreate中获取控件的宽和高
     */
    int iv_height = iv.getHeight();
    int iv_width = iv.getWidth();

    Log.d("tag", "width="+width+"/height="+height+"\niv_width="+iv_width+"/iv_height="+iv_height);

    //3. 分别计算宽和高应该缩放的倍率,然后取最大值Math.max(widht/iv_width,height/iv_height) = smpleSize(缩放比例);
  //sampleSize=0-1之间的话  算作1 
    int sampleSize = Math.max(width/iv_width, height/iv_height);
    Log.d("tag", "sampleSize="+sampleSize);
    //4. 将jpg转换为Bitmap的时候,将sampleSize作为参数传入进去,让API去缩放.得到一个缩放后的bitmap
    opts.inJustDecodeBounds = false;//改为false就代表需要真正的加载图片
    opts.inSampleSize = sampleSize;//设置等比例缩放的倍率 
    Bitmap bitmap = BitmapFactory.decodeFile(file.getAbsolutePath(), opts);

    //5. 将缩放后的bitmap显示到ImageView
    iv.setImageBitmap(bitmap);
  }
}

3. 图片的特效处理

- 01-缩放


public void scale(View view){
    //获取一个logo.png的bitmap形式,然后缩放2倍,然后展示到ImageView
    /*
     * 1. 获取一个模特加载原始Bitmap
     */
    Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.logo);
    /*
     * 2. 创建一张空白的画纸,画纸的大小跟ImageView一样大即可
     */
    Bitmap newBitmap = Bitmap.createBitmap(iv.getWidth(), iv.getHeight(), Config.ARGB_8888);
    /*
     * 3. 将画纸放到画板上
     */
    Canvas canvas = new Canvas(newBitmap);
  //画的方法
    Matrix matrix = new Matrix();
    float[] values = {
        2,0,0,
        0,1,0,
        0,0,1
        };
    matrix.setValues(values);
  //  matrix.setScale(2f, 1f);//这种方法的设置也是可以的
    /*
     * 4. 将模特画到画纸上
     * 参数1:模特对象
     */
    canvas.drawBitmap(bitmap, matrix, null);//画模特时不需要笔
    /*
     * 5. 将画好的纸设置给ImageView
     */
    iv.setImageBitmap(newBitmap);
 }

- 02-平移


public void translate(View view){
/*
 * 1. 获取一个模特加载原始Bitmap
 */
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.logo);
/*
 * 2. 创建一张空白的画纸,画纸的大小跟ImageView一样大即可
 */
Bitmap newBitmap = Bitmap.createBitmap(iv.getWidth(), iv.getHeight(), Config.ARGB_8888);
/*
 * 3. 将画纸放到画板上
 */
Canvas canvas = new Canvas(newBitmap);
Matrix matrix = new Matrix();
//参数1:x方向的平移值
//参数2:y方向的平移值
matrix.setTranslate(20, 20);
//每一个像素点在用矩阵的表示
/*
 * 4. 将模特画到画纸上
 * 参数1:模特对象
 */
canvas.drawBitmap(bitmap, matrix, null);//画模特时不需要笔
/*
 * 5. 将画好的纸设置给ImageView
 */
iv.setImageBitmap(newBitmap);
}

- 03-镜面


public void reverse(View view){
    /*
     * 1. 获取一个模特加载原始Bitmap
     */
    Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.logo);
    /*
     * 2. 创建一张空白的画纸,画纸的大小跟ImageView一样大即可
     */
    Bitmap newBitmap = Bitmap.createBitmap(iv.getWidth(), iv.getHeight(), Config.ARGB_8888);
    /*
     * 3. 将画纸放到画板上
     */
    Canvas canvas = new Canvas(newBitmap);
    Matrix matrix = new Matrix();
    float[] values = {
        1,0,0,
        0,-1,0,
        0,0,1
        };
    matrix.setValues(values);
    //matrix.setScale(1f, 1f);//这种方法的设置也是可以的
    //在让矩阵线y平移一个bitmap的高度值
    //matrix.setTranslate(0, bitmap.getHeight());
    //在原来值的基础上再次修改
    matrix.postTranslate(bitmap.getWidth(),0);
    /*
     * 4. 将模特画到画纸上
     * 参数1:模特对象
     */
    canvas.drawBitmap(bitmap, matrix, null);//画模特时不需要笔
    /*
     * 5. 将画好的纸设置给ImageView
     */
    iv.setImageBitmap(newBitmap);
  }

- 04-倒影


public void reverse(View view){
    /*
     * 1. 获取一个模特加载原始Bitmap
     */
    Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.logo);
    /*
     * 2. 创建一张空白的画纸,画纸的大小跟ImageView一样大即可
     */
    Bitmap newBitmap = Bitmap.createBitmap(iv.getWidth(), iv.getHeight(), Config.ARGB_8888);
    /*
     * 3. 将画纸放到画板上
     */
    Canvas canvas = new Canvas(newBitmap);
    Matrix matrix = new Matrix();
    float[] values = {
        1,0,0,
        0,-1,0,
        0,0,1
        };
    matrix.setValues(values);
  //  matrix.setScale(f, -1f);//这种方法的设置也是可以的
    //在让矩阵线y平移一个bitmap的高度值
//    matrix.setTranslate(0, bitmap.getHeight());
    //在原来值的基础上再次修改
    matrix.postTranslate(0,bitmap.getHeight());
    /*
     * 4. 将模特画到画纸上
     * 参数1:模特对象
     */
    canvas.drawBitmap(bitmap, matrix, null);//画模特时不需要笔
    /*
     * 5. 将画好的纸设置给ImageView
     */
    iv.setImageBitmap(newBitmap);
  }

- 05-旋转


public void rotate(View view){
    /*
     * 1. 获取一个模特加载原始Bitmap
     */
    Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.logo);
    /*
     * 2. 创建一张空白的画纸,画纸的大小跟ImageView一样大即可
     */
    Bitmap newBitmap = Bitmap.createBitmap(iv.getWidth(), iv.getHeight(), Config.ARGB_8888);
    /*
     * 3. 将画纸放到画板上
     */
    Canvas canvas = new Canvas(newBitmap);
    Matrix matrix = new Matrix();
    //默认绕着左上角旋转
    //    matrix.setRotate(10);//0--360    0--2π
    matrix.setRotate(180, bitmap.getWidth()/2, bitmap.getHeight()/2);
    /*
     * 4. 将模特画到画纸上
     * 参数1:模特对象
     */
    canvas.drawBitmap(bitmap, matrix, null);//画模特时不需要笔
    /*
     * 5. 将画好的纸设置给ImageView
     */
    iv.setImageBitmap(newBitmap);
}

4. 实例:随手涂鸦

01-监听事件
02-监听事件
03-保存图片
04-在图库中预览

public class MainActivity extends Activity {
  private ImageView iv;
  private Bitmap bitmap;
  private Canvas canvas;
  private Paint paint;
  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    iv = (ImageView) findViewById(R.id.iv);
    /*
     * 1. 给ImageView设置触摸事件
     */
    /*
     * 2. 当滑动的时候,触摸事件分为3类:
     *  (1). down
     *    记录一下(startX,startY)
     *  (2). move
     *    获取到当前滑动到的坐标(currentX,currentY)
     *    根据两个坐标划线
     *    将画好的Bitmap显示到ImageView上
     *  (3). up
     *    
     */
    iv.setOnTouchListener(new OnTouchListener() {
      private float startX;
      private float startY;
      @Override
      public boolean onTouch(View v, MotionEvent event) {
        switch (event.getAction()) {
        case MotionEvent.ACTION_DOWN:
//          Log.d("tag", "down");
          //获取当前事件的坐标
          startX = event.getX();
          startY = event.getY();
          if (bitmap==null) {
            bitmap = Bitmap.createBitmap(iv.getWidth(), iv.getHeight(), Config.ARGB_8888);
            canvas = new Canvas(bitmap);
            //先给Bitmap绘制成白色的
            canvas.drawColor(Color.WHITE);
            paint = new Paint();
            paint.setColor(Color.RED);
            paint.setStrokeWidth(5);//画笔的粗细 5个像素
          }
          break;
        case MotionEvent.ACTION_MOVE:
//          Log.d("tag", "move");
          float currentX = event.getX();
          float currentY = event.getY();
          //画线
          canvas.drawLine(startX, startY, currentX, currentY, paint);
          //一个新线条的起点就是上一个线条的终点
          startX = currentX;
          startY = currentY;
          iv.setImageBitmap(bitmap);
          break;
        case MotionEvent.ACTION_UP:
//          Log.d("tag", "up");
          break;
        default:
          break;
        }
        //当前ImageView是否将这个事件给消费了
        return true;
      }
    });
  }
  public void save(View view) throws FileNotFoundException{
    //把Bitmap保存到sdcard上jpg
    if (bitmap==null) {
      Toast.makeText(this, "还没画呢,咋保存!", Toast.LENGTH_SHORT).show();
      return;
    }
    File file = new File(Environment.getExternalStorageDirectory(), "yuze_"+new Date().getTime()+".jpg");
    OutputStream fos = new FileOutputStream(file);
    /*
     * 参数1:压缩的格式
     * 参数2:图片的质量
     * 参数3:输出流
     */
    boolean compress = bitmap.compress(CompressFormat.JPEG, 100, fos);
    Toast.makeText(this, compress?"成功":"失败", Toast.LENGTH_SHORT).show();
    //给系统图库发送广播,告诉图库我在sdcard上保存了文件,请求添加到你的预览图中
    Intent intent = new Intent();
    intent.setAction(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
//此处也可以设置挂载内存卡的事件,但4.4后安卓系统在不兼容,只能系统自己内部自己调用.
    intent.setData(Uri.fromFile(file));
    sendBroadcast(intent);
  }
  public void clear(View view){
    bitmap = null;
    iv.setImageBitmap(bitmap);
  }
}


获取屏幕的宽高

5. 实例:撕衣服游戏

01 - 获取屏幕的宽高

//事先已在XML定义好了全景的背景图..
public class MainActivity extends Activity {
  private ImageView iv;
  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    iv = (ImageView) findViewById(R.id.iv);
    // 重新在内存中创建一张空白的纸Bitmap,然后将up.jpg绘制到这张纸上
    // 获取屏幕的宽和高
    Display display = getWindowManager().getDefaultDisplay();
    int width = display.getWidth();
    int height = display.getHeight();
    //获取屏幕宽高的第二种方式:
    // Point outSize = new Point();
    // display.getSize(outSize);
    // outSize.x;outSize.y
    //这是上面的那张图片的位图,原图是不能够修改的,只有创建他的位图的副本才能够修改.
    Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher);
    // 192 288 288 432
    // 由于这个bitmap是来自本地的资源文件,因此该bitmap不能修改,只能读.
    // bitmap.setPixel(20, 20, Color.TRANSPARENT);
    // 在内存中创建一张空白的bitmap才是可以被修改的
    final Bitmap newbitmap = Bitmap.createBitmap(width, height, Config.ARGB_8888);
    Canvas canvas = new Canvas(newbitmap);
    Matrix matrix = new Matrix();// 默认就是单位矩阵
//放大该图片,该图片的真实大小不能够布满整个屏幕
    float[] values = { (width + 0f) / bitmap.getWidth(), 0, 0, 0, (height + 0f) / bitmap.getHeight(), 0, 0, 0, 1
    };
    matrix.setValues(values);
    canvas.drawBitmap(bitmap, matrix, null);
    iv.setImageBitmap(newbitmap);
    // 给ImageView设置手机滑动的监听
    iv.setOnTouchListener(new OnTouchListener() {
      @Override
      public boolean onTouch(View v, MotionEvent event) {
        // 获取到当前触摸到的坐标,建议使用getRawX();
        int x = (int) event.getX();
        int y = (int) event.getY();
        int startX = x - 5;
        int endX = x + 5;
        int startY = y - 5;
        int endY = y + 5;
        for (int i = startX; i < endX; i++) {
          for (int j = startY; j < endY; j++) {
            // 设置像素点不会越界的条件
            if (i > 0 && i < 480 && j > 0 && j < 480) {
             // 将newbitmap对应的(x,y)的像素设置为透明的
             newbitmap.setPixel(i, j, Color.TRANSPARENT);
            }
          }
        }
        // 重新将修改后的newbitmap设置给ImageView
        iv.setImageBitmap(newbitmap);
        return true;
      }
    });
  }
}
2. ImageView(原生)
3. SmartImageView(废弃)
4. Glide(Google)
Glide.with(this).load("http://h.hiphotos.baidu.com/image/pic/item/0ff41bd5ad6eddc49e5987f53bdbb6fd52663305.jpg")
         .crossFade(5000)
         .skipMemoryCache(true)//不使用内存缓存
         .diskCacheStrategy(DiskCacheStrategy.ALL)
         .placeholder(R.drawable.ic_launcher)
         .error(R.drawable.error)
         .into(iv);
5. Picasso(Square)
6. Fresco(FaceBooK)

7. Universal ImageLoader(UIL)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值