图片无限放大,不模糊,图片移动,仿微信图片放大

2019-03-01 23:57|来源: 网路

备注:本文关键内容是“OOM(Out Of Memory)异常",跟 “移动截图起点规则”内容,其他部分没看也可以看的懂


写此程序背景

        看到微信的图片浏览的强大功能,于是自己写了一个。原则上可以无限放大,但是放大部分     像素必须有原图片的1个像素,最小也不能小于1*1像素。

思路:

   功能解剖:

       缩放:微信的缩放能缩放到用户满意的范围。(放大不会超过max倍,缩小不会超过min)

       移动:当图片高与宽小于屏幕时,能移动图片到任意位置。当高或宽大于屏幕时,移动图片则会截取图片某一模块放大满屏显示。

   最重要的一点就是图片放大时看不出来图片变模糊


   解剖雏形:

       假设用系统自带Matrix函数来控制放大缩小。

       缩小:    可以缩小很小倍,当不易控制倍数(如1.25倍,但Matrix不会那么精确)

       放大:但放大超出屏幕时,Bitmap.createBitmap会在内存中创建一个很大的图(或内存超出系统设定的值或宽高超出屏幕),导致显存或内存不足。

       因为上条放大会出现问题所以本方案绝对不行。


   解剖过度:

   那么要有那么一种缩放方法满足下面条件

       一、能几乎精确的缩小到某一个倍数

       二、放大时内存不会溢出

       基于缩放的截取方法想出以下移动方案

       一、当放大时移动时计算某个参考点在图上移动的位置所占比列(x,y),高宽为屏幕高度/倍数

       二、当缩小的图在屏幕范围之内,那么移动的效果通过移动ImageView的位置实现

   方案:因为缩放的关键是放大,所以可以考虑放大时用截取一段图*n倍不会溢出的图

   截图方案: 一、看到截取就想到用画布canvas解决(于是创建了一个MyBitMap类)能截永远不会内存溢出的放大图。并且图像不会模糊(canvas优秀之处)。

补充:OOM(Out Of Memory)异常

1.放大时不模糊的实现:利用canvas获取放大后的图,就能解决安常规放大后模糊的现状。

   2.图片不溢出的实现:在canvas放大时限制图片的大小不超出屏幕就行。

溢出的情况

   一、图片的高或宽超出了屏幕。所以在canvas放大时限制图片的大小不超出屏幕就行。

   二、某一个bitmap超出了系统对单张图片的限制大小5MB(5MB根据系统不同会有差别)。利用canve截图到的图才几十kb。如果利用常规的Matrix在原来的图基础上来放大(放大后的图片大小为原图大小*当前倍数的平方),就会有超限(5MB)溢出。


import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Rect;
import android.widget.ImageView.ScaleType;
/**
 *此处函数是得到剪切的图片
 * @author ZhangJianLin
 *
 */
public class MyBitMap {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 
    public MyBitMap() {
    // TODO Auto-generated constructor stub
}
    /**
     *
     * @param unscaledBitmap the bitmap of source
     * @param dstWidth what width you want to set
     * @param dstHeight What width you want to set
     * @param scalingLogic it is ScaleType
     * @return the scaled bitmap
     */
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 
    public static Bitmap createScaledBitmap(Bitmap unscaledBitmap, int dstWidth, int dstHeight, ScaleType scalingLogic) {
          Rect srcRect = calculateSrcRect(unscaledBitmap.getWidth(), unscaledBitmap.getHeight(), dstWidth, dstHeight, scalingLogic);
          Rect dstRect = calculateDstRect(unscaledBitmap.getWidth(), unscaledBitmap.getHeight(), dstWidth, dstHeight, scalingLogic);
          Bitmap scaledBitmap = Bitmap.createBitmap(dstRect.width(), dstRect.height(), Config.ARGB_8888);
          Canvas canvas = new Canvas(scaledBitmap);
          canvas.drawBitmap(unscaledBitmap, srcRect, dstRect, new Paint(Paint.FILTER_BITMAP_FLAG));
          return scaledBitmap;
          }
    //根据dstWOrH计算原图应该截取的截图合适的高宽比例图
    public static Rect calculateSrcRect(int srcWidth, int srcHeight, int dstWidth, int dstHeight, ScaleType scalingLogic) {
          if (scalingLogic == ScaleType.CENTER_CROP) {
            final float srcAspect = (float)srcWidth / (float)srcHeight;
            final float dstAspect = (float)dstWidth / (float)dstHeight;
            if (srcAspect > dstAspect) {
              final int srcRectWidth = (int)(srcHeight * dstAspect);
              final int srcRectLeft = (srcWidth - srcRectWidth) / 2;
              return new Rect(srcRectLeft, 0, srcRectLeft + srcRectWidth, srcHeight);
            } else {
              final int srcRectHeight = (int)(srcWidth / dstAspect);
              final int scrRectTop = (int)(srcHeight - srcRectHeight) / 2;
              return new Rect(0, scrRectTop, srcWidth, scrRectTop + srcRectHeight);
            }
          } else {
            return new Rect(0, 0, srcWidth, srcHeight);
          }
        }
    //根据dstWOrH计算原图应该截取的期望图合适的高宽比例图
        public static Rect calculateDstRect(int srcWidth, int srcHeight, int dstWidth, int dstHeight, ScaleType scalingLogic) {
          if (scalingLogic == ScaleType.FIT_XY) {
            final float srcAspect = (float)srcWidth / (float)srcHeight;
            final float dstAspect = (float)dstWidth / (float)dstHeight;
            if (srcAspect > dstAspect) {
              return new Rect(0, 0, dstWidth, (int)(dstWidth / srcAspect));
            } else {
              return new Rect(0, 0, (int)(dstHeight * srcAspect), dstHeight);
            }
          } else {
            return new Rect(0, 0, dstWidth, dstHeight);
          }
        }
        /**
         *
         * @param unscaledBitmap the bitmap of source
         * @param scale the scale you want
         * @param scalingLogic it is ScaleType
         * @return the scaled bitmap
         */
        //根据放大倍数获得截取图安scale放大的图
        public static Bitmap createBMScaleBitmap(Bitmap unscaledBitmap, Double scale, ScaleType scalingLogic){
        int dstWidth = (int)(unscaledBitmap.getWidth()* scale);
        int dstHeight = (int)(unscaledBitmap.getHeight()*scale);
        return createScaledBitmap(unscaledBitmap, dstWidth, dstHeight, scalingLogic);
    }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 
}



移动截图起点规则

          每缩放一次,就以图的中心为截获图的中心(Ox,Oy),起点为(Ox-needwidth/2,Oy - needhight/2)。

          在缩放时,把放大后的图在逻辑上的坐标划分为m份,(1单位为屏幕的宽或高),同时每移动一次,就移动1/4份(即每次移动1/4屏幕)。 (单次移动的宽或高像素为                (bitmapWidth/m*n或bitmapHight/m*n,其中n是缩放的倍数,m为计算缩放后的图片高宽跟屏幕对应的宽高的比例,以此得到的值作为x或y的坐标最大值,坐标单位为一个屏幕,每滑次移动半个屏幕或1/3屏幕

         结合安卓的滑动或移动的灵敏度,能完美的模拟出效果图(亲测,如果移动规则用跟踪手的移动位移来移动图片是行不通的,不知道市面上能作出这样的效果是什么样的一个算法,还有待探究)
核心实现代码及注释如下

package com.imageopen;
import android.app.Activity;
import android.graphics.Bitmap;
import android.os.Bundle;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.Menu;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnTouchListener;
import android.view.Window;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.ImageView.ScaleType;
public class BigzoonImage extends Activity {
    ImageView myImageView;
    Button bigButton;//放大按钮
    Button smallButton;//缩小按钮
    View myButtons;
    private Bitmap myBitmap;
    private double bigSize = 1.25;//每次放大的比列
    private double smallSize = 0.8;//每次缩小的比例
    double size = 1;//当前放大的倍数
    double pixel = 30.00;//限制图片缩小时的最小像素
    int bmpWidth;//图片宽度
    int bmpHight;//图片高度
    int bmpSizeWidth;//放大后的图片宽度bmpwidth*size
    int bmpSizeHight;
    int x ;//
    int y ;//
    int screenWidth;      // 屏幕宽(像素,如:480px)
    int screenHeight;     // 屏幕高(像素,如:800px)
    int dstHeight;
    int dstWidth;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        super.onCreate(savedInstanceState);
        setContentView(R.layout.bigzoonimage_main);
        init();
    }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           
    private void init(){//初始化各参数的值
        myImageView = (ImageView)findViewById(R.id.bitmap_image);
        bigButton = (Button)findViewById(R.id.button_big);
        smallButton = (Button)findViewById(R.id.button_small);
        myButtons = (View)findViewById(R.id.bitmap_button);
        MyBitmapFactory myBitmapFactory = new MyBitmapFactory(this);
        myBitmap = myBitmapFactory.getDrawBmp(R.drawable.bitmap_test);//事先加载一张图片
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               
        myImageView.setImageBitmap(myBitmap);
        myImageView.setOnTouchListener(ImageOpenListener);
        bigButton.setOnClickListener(sizeButton);//添加按钮触发事件
        smallButton.setOnClickListener(sizeButton);//同上
        DisplayMetrics dm = new DisplayMetrics();  //声明一个屏幕像素的类屏幕像素
        dm = getResources().getDisplayMetrics();  //得到屏幕像素
        screenWidth  = dm.widthPixels;      // 屏幕宽(像素,如:480px)
        screenHeight = dm.heightPixels;     // 屏幕高(像素,如:800px)
    }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           
    private void big(){//放大时图片的变化
        size = bigSize * size;
        Bitmap newBitmap = myBitmap;
        newBitmap = bigCal(myBitmap);
        newBitmap = MyBitMap.createScaledBitmap(newBitmap, dstWidth, dstHeight, ScaleType.FIT_XY);
        myImageView.setImageBitmap(newBitmap);
    }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           
    private void small(){//缩小时图片的变化
        size = smallSize * size;
        Bitmap newBitmap = myBitmap;//得到原图的截取图
        newBitmap = bigCal(newBitmap);
        newBitmap = MyBitMap.createScaledBitmap(newBitmap, dstWidth, dstHeight, ScaleType.FIT_XY);
        myImageView.setImageBitmap(newBitmap);
    }
    private OnClickListener sizeButton = new OnClickListener() {//放大缩小的事件
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               
        @Override
        public void onClick(View v) {
            // TODO Auto-generated method stub
            if(v == bigButton){
                big();
                }
            else small();
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   
        }
    };
    //每缩放一次,就以图的中心为截获图的中心(Ox,Oy),起点为(Ox-needwidth/2,Oy - needhight/2),宽高为屏幕宽高的图。
    public Bitmap bigCal(Bitmap bitmap){//缩放得到原图的截取图
        bmpWidth = bitmap.getWidth();
        bmpHight = bitmap.getHeight();
        //放大的size最小值,16是指限制的截取的图片最小像素,要是缩小的很小,那么一丁点没有意义,这里的16看个人意思
        int sizeMax = Math.min(myBitmap.getWidth()/16, myBitmap.getHeight()/16);//限定放大的最大倍数
        double sizeMin = Math.max(pixel/myBitmap.getWidth(), pixel/myBitmap.getHeight());//限制缩小的size最小倍数
        if(size > sizeMax){
            size = sizeMax;
        }
        if(size < sizeMin){
            size = sizeMin;
        }
        bmpSizeWidth = (int)(bmpWidth*size);
        bmpSizeHight = (int)(bmpHight*size);
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               
        if(screenWidth > bmpSizeWidth){
            x = 0;
            dstWidth = bmpSizeWidth;
        }else{
            x = (int)((bmpSizeWidth - screenWidth)/(2*size));
            bmpWidth = (int)(screenWidth / size);
            dstWidth = screenWidth;
        }
        if(screenHeight > bmpSizeHight){
            y = 0;
            dstHeight = bmpSizeHight;
        }else{
            y = (int)((bmpSizeHight - screenHeight)/(2*size));//放大时计算以中心的为截取中心的所要截图的左上点坐标(x,y)
            bmpHight = (int)(screenHeight / size);
            dstHeight = screenHeight;
        }
        bitmap = Bitmap.createBitmap(bitmap, x, y, bmpWidth, bmpHight);
        return bitmap;
        }
    //计算缩放的倍数跟屏幕的比例,以得到的值作为x或y的坐标最大值,坐标单位为一个屏幕,每滑动次移动半个屏幕或1/3屏幕
    public double rowOrCowNum(int sizeBitmapWH, int screenWH){
        double num = (sizeBitmapWH * size)/screenWH;
        return num;
    }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           
    public Bitmap movCal(Bitmap bitmap, int dx, int dy){//计算移动后的要截取的图
        double coordinateX = rowOrCowNum(myBitmap.getWidth() , screenWidth);//缩放后x坐标,
        double coordinateY = rowOrCowNum(myBitmap.getHeight(), screenHeight);//缩放后y的坐标
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               
        if(coordinateX > 1){
            if(dx > 0){
            x -= (myBitmap.getWidth()/(coordinateX * 4));
            if(x < 0){
                x = 0;
            }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   
            }
            if(dx < 0){
                x += (myBitmap.getWidth()/(coordinateX *4));
                if(x > (myBitmap.getWidth() - bmpWidth)){
                    x = myBitmap.getWidth() - bmpWidth;
                }
            }
        }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   
            if(coordinateY > 1){
                if(dy > 0){
                y -= (myBitmap.getHeight()/(coordinateY * 4));
                if(y < 0){
                    y = 0;
                }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       
                }
                if(dy < 0){
                    y += (myBitmap.getHeight()/(coordinateY *4));
                    if(y > (myBitmap.getHeight() - bmpHight)){
                        y = myBitmap.getHeight() - bmpHight;
                    }
                }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   
        }
        bitmap = Bitmap.createBitmap(bitmap, x, y, bmpWidth, bmpHight);
        bitmap = MyBitMap.createScaledBitmap(bitmap, dstWidth, dstHeight, ScaleType.FIT_XY);
        return bitmap;
    }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           
    private OnTouchListener ImageOpenListener = new OnTouchListener() {//移动监听
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               
        int lastX;
        int lastY;
        int left;//图片的左边界的坐标
        int right;//图片右边界坐标
        int top;//图片上边界的坐标
        int bottom;//图片下边界的坐标
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            // TODO Auto-generated method stub
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   
            switch(event.getAction()){
            case MotionEvent.ACTION_DOWN:
                lastX = (int)event.getRawX();
                lastY = (int)event.getRawY();
                break;
            case MotionEvent.ACTION_MOVE:
                int dx = (int)event.getRawX() - lastX;//dx为在屏幕的x轴上移动的距离
                int dy = (int)event.getRawY() - lastY;//dy为在屏幕的y轴上移动的距离
                Bitmap newBitmap;
                //计算缩放的图片是否找出屏幕范围,如果是
                if(bmpSizeWidth > screenWidth||bmpSizeHight > screenHeight){
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           
                    if(bmpSizeWidth > screenWidth){
                        left = 0;
                        right = screenWidth;
                    }else{
                        left = v.getLeft() + dx;
                        right = v.getRight() + dx;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               
                    }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           
                    if(bmpSizeHight > screenHeight){
                        top = 0;
                        bottom = screenHeight;
                    }else {
                        top = v.getTop() + dy;
                        bottom = v.getBottom() + dy;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           
                    }
                    if((dx > 3 || dx < -3) && (dy > 3 ||dy  < -3)){//设置灵敏度,一定要设置
                    newBitmap = movCal(myBitmap, dx, dy);
                    myImageView.setImageBitmap(newBitmap);
                    }
                }
                else{//如果没有超出则移动ImageView
                    left = v.getLeft() + dx;
                    top = v.getTop() + dy;
                    bottom = v.getBottom() + dy;
                    right = v.getRight() + dx;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       
                }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       
                v.layout(left, top, right, bottom);
                lastX = (int)event.getRawX();
                lastY = (int)event.getRawY();
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       
                break;
            }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   
            return true;
        }
    };
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           
    @Override
    protected void onPause() {
        // TODO Auto-generated method stub
        System.exit(0);
        super.onPause();
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               
    }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           
    @Override
    protected void onStop() {
        // TODO Auto-generated method stub
        System.exit(0);
        super.onStop();
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               
    }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.activity_main, menu);
        return true;
    }
}


 另外有一个辅助类,就是获取各类渠道图片的封装类

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Bitmap.CompressFormat;
import android.graphics.Bitmap.Config;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.LinearGradient;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.PorterDuff.Mode;
import android.graphics.PorterDuffXfermode;
import android.graphics.Shader.TileMode;
import android.util.Base64;
/**
 * 功能:得到原始的bitmap,就是unscaledbitmap;将得到bitmap字节流
 * @author ZhangJianLin
 *
 */
public class MyBitmapFactory {
    Context context;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      
    public MyBitmapFactory(Context context) {
    // TODO Auto-generated constructor stub
        this.context = context;
}
    public Bitmap getFileBmp(String path){//通过路径获得图片
        Bitmap bm = BitmapFactory.decodeFile(path);
        return bm;
    }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      
    public Bitmap getDrawBmp(int id){//通过本项目id获得图片
        Bitmap bm = BitmapFactory.decodeResource(context.getResources(), id);
        return bm;
    }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      
    public Bitmap getStringBmp(InputStream inputstring){//从流中获取图片
        Bitmap bm = BitmapFactory.decodeStream(inputstring);
        return bm;
    }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      
    public Bitmap getArrayBmp(byte[] data, int offset, int length){//从字节转化成图片
        Bitmap bm = BitmapFactory.decodeByteArray(data, offset, length);
        return bm;
    }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      
    //获得带倒影的图片方法
    public static Bitmap createReflectionImageWithOrigin(Bitmap bitmap){
    final int reflectionGap = 4;
    int width = bitmap.getWidth();
    int height = bitmap.getHeight();
    Matrix matrix = new Matrix();
    matrix.preScale(1, -1);
    Bitmap reflectionImage = Bitmap.createBitmap(bitmap,
    0, height/2, width, height/2, matrix, false);
    Bitmap bitmapWithReflection = Bitmap.createBitmap(width, (height + height/2),
    Config.ARGB_8888);
    Canvas canvas = new Canvas(bitmapWithReflection);
    canvas.drawBitmap(bitmap, 0, 0, null);
    Paint deafalutPaint = new Paint();
    canvas.drawRect(0, height,width,height + reflectionGap,
    deafalutPaint);
    canvas.drawBitmap(reflectionImage, 0, height + reflectionGap, null);
    Paint paint = new Paint();
    LinearGradient shader = new LinearGradient(0,
    bitmap.getHeight(), 0, bitmapWithReflection.getHeight()
    + reflectionGap, 0x70ffffff, 0x00ffffff, TileMode.CLAMP);
    paint.setShader(shader);
    // Set the Transfer mode to be porter duff and destination in
    paint.setXfermode(new PorterDuffXfermode(Mode.DST_IN));
    // Draw a rectangle using the paint with our linear gradient
    canvas.drawRect(0, height, width, bitmapWithReflection.getHeight()
    + reflectionGap, paint);
    return bitmapWithReflection;
    }
    public Bitmap stringtoBitmap(String string){//从string到bitmap
        //将字符串转换成Bitmap类型
        Bitmap bitmap=null;
        try {
        byte[]bitmapArray;
        bitmapArray=Base64.decode(string, Base64.DEFAULT);
    bitmap=BitmapFactory.decodeByteArray(bitmapArray, 0, bitmapArray.length);
    } catch (Exception e) {
    e.printStackTrace();
    }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         
        return bitmap;
        }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           
        public String bitmaptoString(Bitmap bitmap){
    //将Bitmap转换成字符串
        String string=null;
        ByteArrayOutputStream bStream=new ByteArrayOutputStream();
        bitmap.compress(CompressFormat.PNG,100,bStream);
        byte[]bytes=bStream.toByteArray();
        string=Base64.encodeToString(bytes,Base64.DEFAULT);
        return string;
        }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          
        public Bitmap returnBitMap(String url) {//从网络中获得图片
            URL myFileUrl = null;
            Bitmap bitmap = null;
            try {
                    myFileUrl = new URL(url);
            } catch (MalformedURLException e) {
                    e.printStackTrace();
            }
            try {
                    HttpURLConnection conn = (HttpURLConnection) myFileUrl
                                    .openConnection();
                    conn.setDoInput(true);
                    conn.connect();
                    InputStream is = conn.getInputStream();
                    bitmap = BitmapFactory.decodeStream(is);
                    is.close();
            } catch (IOException e) {
                    e.printStackTrace();
            }
            return bitmap;
    }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          
}


本实验中所用到的布局如下

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity" >
    <ImageView
        android:id="@+id/bitmap_image"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:layout_centerVertical="true"
        android:src="@drawable/ic_launcher" />
    <LinearLayout
        android:id="@+id/bitmap_button"
        android:layout_width="80dp"
        android:layout_height="40dp"
        android:layout_alignParentBottom="true"
        android:layout_alignParentLeft="true"
        android:layout_marginBottom="16dp"
        android:layout_marginLeft="14dp"
        android:orientation="horizontal" >
        <Button
            android:id="@+id/button_small"
            android:layout_width="40dp"
            android:layout_height="40dp"
            android:background="@drawable/bitmap_small" />
        <Button
            android:id="@+id/button_big"
            android:layout_width="40dp"
            android:layout_height="40dp"
            android:background="@drawable/bitmap_big" />
    </LinearLayout>
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             
</RelativeLayout>


效果如下图

原图:




放大后



本实验有如下缺陷:(很容易改进)

       1、移动时给用户的体验还不错。有一点点缺陷

       2、放大时image边上有空白,这是因为计算截图时的误差

改进思路:

对于一、改进移动时的x,y及每次移动的算法规则;每次移动的距离为屏幕的1/m,提高m值,或用算法动态改变m值

       对于二、当放大后的图像的宽高都大于屏幕的宽高,截获放大后的图设为全屏背景


源码地址http://pan.baidu.com/share/link?shareid=480398&uk=2065228996,编码是utf-8



本文出自 “lilin9105” 博客,请务必保留此出处http://7071976.blog.51cto.com/7061976/1208469


转自:http://7071976.blog.51cto.com/7061976/1208469

相关问答

更多
  • 放大像素会失真,如果你要实现这一共能的话可以用JLabel来显示图片。有一个方法可以实现图片的缩放ImageIcon ii = new ImageIcon("img/item.jpg"); Image img = ii.getImage(); img = img.getScaledInstance(100, 100, Image.SCALE_DEFAULT); ii = new ImageIcon(img);这个例子的getScaledInstance方法可以生成一个新的Image对象,可以缩放成指定的大小 ...
  • 下载envice-gtk等pdf阅读软件 以下软件可选,都是pdf阅读软件 atril evince gv mupdf okular viewpdf.app xpdf zathura
  • 小程序是一种不需要下载安装即可使用的应用,它实现了应用“触手可及”的梦想,用户扫一扫或者搜一下即可打开应用。也体现了“用完即走”的理念,用户不用关心是否安装太多应用的问题。应用将无处不在,随时可用,但又无需安装卸载。对于开发者而言,小程序开发门槛相对较低,难度不及APP,能够满足简单的基础应用,适合生活服务类线下商铺以及非刚需低频应用的转换。小程序能够实现消息通知、线下扫码、公众号关联等七大功能。其中,通过公众号关联,用户可以实现公众号与小程序之间相互跳转。由于小程序不存在入口。
  • 可以用 Css3 的动画效果: @-webkit-keyframes sigma{ 0% {transform: scale(1);} 100% {transform: scale(2);} } .easeBg{ transform-origin: center; animation: sigma 1s; overflow: hidden; }
  • 好吧,我下载了你的代码并搞砸了它。 删除max-width: 100%; 从img CSS似乎已经修复它(第25行)。 将来,请将代码与您的问题一起发布,或者如果有很多部分, JSFiddle也是可以接受的。 谢谢。 Alright, I downloaded your code and messed around with it. Removing max-width: 100%; from the img CSS seems to have fixed it (line 25). In the futu ...
  • 只需在标签内设置高度和宽度,或者使用css 例: simply set the height and width inside the tag, or use css example:
    如上所述,一种方法是使用transform: scale(2); 另一个简单的方法是: document.querySelector('img.sample-image').addEventListener('click', function() { this.classList.toggle('sample-image-large'); }); .sample-image { transition:all 1s ease; width: 100%; } .sampl ...
  • 尝试这个:- $('img').load(function() { $(this).data('height', this.height); }) $('.imagen').on('mouseenter mouseleave', function(e) { var img = $(this).children('img'); $(img).stop().animate({ height: $(img).data('height') * (e.type === 'mo ...
  • 有许多不同的调整大小算法提供不同的质量水平,权衡是cpu时间。 我相信你应该能够相对容易地处理块中的大量文件,但是,您应该尝试使用现有工具来查看它们是否已经可以只处理大量文件。 Gd图形库允许您定义它可以使用多少工作内存我相信它显然已经具有处理文件块的逻辑。 There are a lot of different resizing algorithms which offer varying level of quality with the trade off being cpu time. I bel ...