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

简介:

备注:本文关键内容是“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)溢出。


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
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屏幕

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
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 ;
     }
}


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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
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;
     }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           
}


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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
< 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 >


效果如下图

原图:


214337724.jpg


放大后

214337371.jpg



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

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

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

改进思路:

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

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




本文转自lilin9105 51CTO博客,原文链接:http://blog.51cto.com/7071976/1208469,如需转载请自行联系原作者

相关文章
|
3月前
|
机器学习/深度学习 小程序 前端开发
微信小程序——实现对话模式(调用大模型图片生成)
微信小程序——实现对话模式(调用大模型图片生成)
261 3
|
3月前
【微信公众平台对接】有关【上传图文消息内的图片获取URL】调用示例
【微信公众平台对接】有关【上传图文消息内的图片获取URL】调用示例
110 0
|
3月前
|
前端开发 小程序
微信小程序canvas画布绘制base64图片并保存图片到相册中
微信小程序canvas画布绘制base64图片并保存图片到相册中
148 0
|
1月前
|
小程序 开发者
【微信小程序-原生开发】实用教程05-首页(含自定义调试模式、插入图片、图文排版、底部留白、添加本地图片)
【微信小程序-原生开发】实用教程05-首页(含自定义调试模式、插入图片、图文排版、底部留白、添加本地图片)
25 0
|
1月前
|
小程序 前端开发
【非常全】微信小程序下载图片到相册,微信小程序自动获取分享图片到相册
【非常全】微信小程序下载图片到相册,微信小程序自动获取分享图片到相册
107 3
|
1月前
|
前端开发 小程序
【微信小程序-原生开发】实用教程20 - 生成海报(实战范例为生成活动海报,内含生成指定页面的小程序二维码,保存图片到手机,canvas 系列教程)
【微信小程序-原生开发】实用教程20 - 生成海报(实战范例为生成活动海报,内含生成指定页面的小程序二维码,保存图片到手机,canvas 系列教程)
122 0
|
1月前
|
小程序 JavaScript 前端开发
【微信小程序-原生开发】实用教程06-轮播图、分类页签 tab 、成员列表(含Tdesign升级,切换调试基础库,设置全局样式,配置组件按需注入,添加图片素材,wx:for,生命周期 onLoad)
【微信小程序-原生开发】实用教程06-轮播图、分类页签 tab 、成员列表(含Tdesign升级,切换调试基础库,设置全局样式,配置组件按需注入,添加图片素材,wx:for,生命周期 onLoad)
36 0
|
2月前
|
小程序 API
技术心得记录:微信小程序之图片频繁变化,几秒之后输出结果(适用于抽奖)
技术心得记录:微信小程序之图片频繁变化,几秒之后输出结果(适用于抽奖)
20 0
|
2月前
|
开发工具
云控微信开发SDK使用教程--手机微信朋友圈图片上传服务端
云控微信开发SDK使用教程--手机微信朋友圈图片上传服务端
|
3月前
|
机器学习/深度学习 自然语言处理 计算机视觉
CVPR 2024:生成不了光线极强的图片?微信视觉团队有效解决扩散模型奇点问题
【4月更文挑战第14天】中山大学和微信团队的研究者提出 SingDiffusion,一种解决扩散模型在处理极端亮度图像时的平均亮度问题的新方法。SingDiffusion 可无缝集成到预训练模型中,无需额外训练,通过处理 t=1 时间步长的采样问题,改善了图像生成的亮度偏差。在 COCO 数据集上的实验显示,相较于现有模型,SingDiffusion 在 FID 和 CLIP 分数上表现更优。
49 7
CVPR 2024:生成不了光线极强的图片?微信视觉团队有效解决扩散模型奇点问题

热门文章

最新文章