Internship 8th day: SurfaceView implementation picture zoom drag function

Original address: http://blog.csdn.net /sunnyfans/article/details/17969531

Question: Adopt Surface to achieve multi-touch zoom, drag display function.

[java] view plain copy

View code on CODE Chips < span class="tracking-ad">derived To my code piece

  1. publicclassMySurfaceView3extends SurfaceViewimplements
  2. SurfaceHolder.Callback, OnTouchListener {
  3. privatestaticfinalintNONE=0;// Original
  4. privatestaticfinalintDRAG=1;// Drag
  5. privatestaticfinalintZOOM= 2< span style="margin:0px; padding:0px; border:none; background-color:inherit">;// zoom in
  6. privateint< span style="margin:0px; padding:0px; border:none; background-color:inherit">mStatus=NONE;
  7. privatestaticfinalfloatMAX_ZOOM_SCALE=4.0f; span>
  8. privatestaticfinalfloatMIN_ZOOM_SCALE=1.0f;
  9. privatestaticfinalfloat FLOAT_TYPE=1.0f;
  10. privatefloatmCurrentMaxScale=MAX_ZOOM_SCALE;
  11. privatefloatmCurrentScale=1.0f;
  12. privateRect mRectSrc=new Rect();//used for render image.
  13. private Rect mRectDes=new Rect();// used for store size of monitor.
  14. privateint< /span>mCenterX,mCenterY;
  15. intmSurfaceHeight, mSurfaceWidth, mImageHeight, mImageWidth;
  16. span class=”keyword” style=”margin:0px; padding:0px; border:none; color:rgb(0,102,153); font-weight:bold; background-color:inherit”>privatePointFmStartPoint=newPointF( );
  17. privatefloatmStartDistance= 0f; span>
  18. private SurfaceHolder mSurHolder=null;
  19. privateBitmap mBitmap; ​​/span>
  20. publicMySurfaceView3(Contextcontext,AttributeSetattrs){< /span>
  21. super (context,attrs);
  22. mSurHolder = GetHolder();
  23. mSurHolder.addCallback(this);
  24. this.setOnTouchListener(this);
  25. privatevoid init() {  
  26.         mCurrentMaxScale = Math.max(  
  27.                 MIN_ZOOM_SCALE,  
  28.                 4 * Math.min(FLOAT_TYPE * mImageHeight / mSurfaceHeight, 1.0f  
  29.                         * mImageWidth / mSurfaceWidth));  
  30.         mCurrentScale = MIN_ZOOM_SCALE;  
  31.         mCenterX = mImageWidth / 2;  
  32.         mCenterY = mImageHeight / 2;  
  33.         calcRect();  
  34.   
  35.     }  
  36.   
  37.     private void adjustCen ter() {  
  38.         int w = mRectSrc.right – mRectSrc.left;  
  39.         int h = mRectSrc.bottom – mRectSrc.top;  
  40.   
  41.         if (mCenterX – w / 2 < 0) {  
  42.             mCenterX = w / 2;  
  43.             mRectSrc.left = 0;  
  44.             mRectSrc.right = w;  
  45.         } else if (mCenterX + w / 2 >= mImageWidth) {  
  46.             mCenterX = mImageWidth – w / 2;  
  47.             mRectSrc.right = mImageWidth;  
  48.             mRectSrc.left = mRectSrc.right – w;  
  49.   
  50.         } else {  
  51.             mRectSrc.left = mCenterX – w / 2;  
  52.             mRectSrc.right = mRectSrc.left + w;  
  53.         }  
  54.   
  55.         if (mCenterY – h / 2 < 0) {  
  56.             mCenterY = h / 2;  
  57.             mRectSrc.top = 0;  
  58.             mRectSrc.bottom = h;  
  59.         } else if (mCenterY + h / 2 >= mImageHeight) {  
  60.             mCenterY = mImageHeight – h / 2;  
  61.             mRectSrc.bottom = mImageHeight;  
  62.             mRectSrc.top = mRectSrc.bottom – h;  
  63.         } else {  
  64.             mRectSrc.top = mCenterY – h / 2;  
  65.             mRectSrc.bottom = mRectSrc.top + h;  
  66.         }  
  67.   
  68.     }  
  69.   
  70.     private void calcRect() {  
  71.         int w, h;  
  72.         float imageRatio, surfaceRatio;  
  73.         imageRatio = FLOAT_TYPE * mImageWidth / mImageHeight;  
  74.         surfaceRatio = FLOAT_TYPE * mSurfaceWidth / mSurfaceHeight;  
  75.   
  76.         if (imageRatio < surfaceRatio) {  
  77.             h = mSurfaceHeight;  
  78.             w = (int) (h * imageRatio);  
  79.         } else {  
  80.             w = mSurfaceWidth;  
  81.             h = (int) (w / imageRatio);  
  82.         }  
  83.   
  84.         if (mCurrentScale > MIN_ZOOM_SCALE) {  
  85.             w = Math.min(mSurfaceWidth, (int) (w * mCurrentScale));  
  86.             h = Math.min(mSurfaceHeight, (int) (h * mCurrentScale));  
  87.         } else {  
  88.             mCurrentScale = MIN_ZOOM_SCALE;  
  89.         }  
  90.   
  91.         mRectDes.left = (mSurfaceWidth – w) / 2;  
  92.         mRectDes.top = (mSurfaceHeight – h) / 2;  
  93.         mRectDes.right = mRectDes.left + w;  
  94.         mRectDes.bottom = mRectDes.top + h;  
  95.   
  96.         float curImageRatio = FLOAT_TYPE * w / h;  
  97.         int h2, w2;  
  98.         if (curImageRatio > imageRatio) {  
  99.             h2 = (int) (mImageHeight / mCurrentScale);  
  100.             w2 = (int) (h2 * curImageRatio);  
  101.         } else {  
  102.   
  103.             w2 = (int) (mImageWidth / mCurrentScale);  
  104.             h2 = (int) (w2 / curImageRatio);  
  105.         }  
  106.         mRectSrc.left = mCenterX – w2 / 2;  
  107.         mRectSrc.top = mCenterY – h2 / 2;  
  108.         mRectSrc.right = mRectSrc.left + w2;  
  109.         mRectSrc.bottom = mRectSrc.top + h2;  
  110.     }  
  111.   
  112.     public void setMaxZoom(float value) {  
  113.         mCurrentMaxScale = value;  
  114.     }  
  115.   
  116.     public void setBitmap(Bitmap b) {  
  117.   
  118.         if (b == null) {  
  119.             return;  
  120.         }  
  121.         synchronized (MySurfaceView3.class) {  
  122.             mBitmap = b;  
  123.             if (mImageHeight != mBitmap.getHeight()  
  124.                     || mImageWidth != mBitmap.getWidth()) {  
  125.                 mImageHeight = mBitmap.getHeight();  
  126.                 mImageWidth = mBitmap.getWidth();  
  127.                 init();  
  128.             }  
  129.             showBitmap();  
  130.         }  
  131.   
  132.     }  
  133.   
  134.     private void showBitmap() {  
  135.         synchronized (MySurfaceView3.class) {  
  136.             Canvas c = getHolder().lockCanvas();  
  137.             if (c != null && mBitmap != null) {  
  138.                 c.drawColor(Color.GRAY);  
  139.                 c.drawBitmap(mBitmap, mRectSrc, mRectDes, null);  
  140.                 getHolder().unlockCanvasAndPost(c);  
  141.             }  
  142.         }  
  143.     }  
  144.   
  145.     private void dragAction(MotionEvent event) {  
  146.   
  147.         synchronized (MySurfaceView3.class) {  
  148.             PointF currentPoint = new PointF();  
  149.             currentPoint.set(event.getX(), event.getY());  
  150.             int offsetX = (int) currentPoint.x – (int) mStartPoint.x;  
  151.             int offsetY = (int) currentPoint.y – (int) mStartPoint.y;  
  152.             mStartPoint = currentPoint;  
  153.   
  154.             mCenterX -= offsetX;  
  155.             mCenterY -= offsetY;  
  156.   
  157.             adjustCenter();  
  158.             showBitmap();  
  159.         }  
  160.     }  
  161.   
  162.     private void zoomAcition(MotionEvent event) {  
  163.   
  164.         synchronized (MySurfaceView3.class) {  
  165.   
  166.             float newDist = spacing(event);  
  167.             float scale = newDist / mStartDistance;  
  168.             mStartDistance = newDist;  
  169.   
  170.             mCurrentScale *= scale;  
  171.             mCurrentScale = Math.max(FLOAT_TYPE,  
  172.                     Math.min(mCurrentScale, mCurrentMaxScale));  
  173.   
  174.             calcRect();  
  175.             adjustCenter();  
  176.             showBitmap();  
  177.         }  
  178.     }  
  179.   
  180.     @Override  
  181.     public boolean onTouch(View v, MotionEvent event) {  
  182.   
  183.         switch (event.getAction() & MotionEvent.ACTION_MASK) {  
  184.         case MotionEvent.ACTION_DOWN:  
  185.             mStartPoint.set(event.getX(), event.getY());  
  186.             mStatus = DRAG;  
  187.             break;  
  188.   
  189.         case MotionEvent.ACTION_POINTER_DOWN:  
  190.             float distance = spacing(event);  
  191.             if (distance > 10f) {  
  192.   
  193.                 mStatus = ZOOM;  
  194.                 mStartDistance = distance;  
  195.             }  
  196.   
  197.             break;  
  198.   
  199.         case MotionEvent.ACTION_MOVE:  
  200.             if (mStatus == DRAG) {  
  201.                 dragAction(event);  
  202.             } else {  
  203.   
  204.                 if (event.getPointerCount() == 1)  
  205.                     return true;  
  206.                 zoomAcition(event);  
  207.             }  
  208.             b reak;  
  209.         case MotionEvent.ACTION_UP:  
  210.         case MotionEvent.ACTION_POINTER_UP:  
  211.             mStatus = NONE;  
  212.             break;  
  213.         default:  
  214.             break;  
  215.         }  
  216.   
  217.         return t rue;  
  218.     }  
  219.   
  220.     private float spacing(MotionEvent event) {  
  221.         float x = event.getX(0) – event.getX(1);  
  222.         float y = event.getY(0) – event.getY(1);  
  223.         return (float) Math.sqrt(x * x + y * y);  
  224.     }  
  225. < li class="alt" style="border-style:none none none solid; border-left-width:3px; border-left-color:rgb(108,226,108); list-style:decimal-leading-zero outside; color:inherit; line-height:18px; margin:0px!important; padding:0px 3px 0px 10px!important">   

  226.     @Override  
  227.     public void surfaceCreated(SurfaceHolder holder) {  
  228.         // TODO Auto-generated method stub  
  229.     }  
  230.   
  231.     // 初始化  
  232.     @Override  
  233.     public void surfaceChanged(SurfaceHolder holder, int format, int width,  
  234.             int height) {  
  235.   
  236.         synchronized (MySurfaceView3.class) {  
  237.             mRectDes.set(00, width, height);  
  238.             mSurfaceHeight = height;  
  239.             mSurfaceWidth = width;  
  240.             init();  
  241.             if (mBitmap != null) {  
  242.                 showBitmap();  
  243.             }  
  244.         }  
  245.     }  
  246.   
  247.     @Override  
  248.     public void surfaceDestroyed(SurfaceHolder holder) {  
  249.   
  250.     }  
  251.   
  252. }  

[java]  view plain  copy

  在CODE上查看代码片 派生到我的代码片

  1. public class MySurfaceView3 extends SurfaceView implements  
  2.         SurfaceHolder.Callback, OnTouchListener {  
  3.   
  4.     private static final int NONE = 0;// 原始  
  5.     private static final int DRAG = 1;// 拖动  
  6.     private static final int ZOOM = 2;// 放大  
  7.     private int mStatus = NONE;  
  8.   
  9.     private static final float MAX_ZOOM_SCALE = 4.0f;  
  10.     private static final float MIN_ZOOM_SCALE = 1.0f;  
  11.     private static final float FLOAT_TYPE = 1.0f;  
  12.     private float mCurrentMaxScale = MAX_ZOOM_SCALE;  
  13.     private float mCurrentScale = 1.0f;  
  14.   
  15.     private Rect mRectSrc = new Rect(); // used for render image.  
  16.     private Rect mRectDes = new Rect(); // used for store size of monitor.  
  17.   
  18.     private int mCenterX, mCenterY;  
  19.     int mSurfaceHeight, mSurfaceWidth, mImageHeight, mImageWidth;  
  20.   
  21.     private PointF mStartPoint = new PointF();  
  22.     private float mStartDistance = 0f;  
  23.   
  24.     private SurfaceHolder mSurHolder = null;  
  25.     private Bitmap mBitmap;  
  26.   
  27.     public MySurfaceView3(Context context, AttributeSet attrs) {  
  28.         super(context, attrs);  
  29.         mSurHolder = getHolder();  
  30.         mSurHolder.addCallback(this);  
  31.         this.setOnTouchListener(this);  
  32.   
  33.     }  
  34.   
  35.     private void init() {  
  36.         mCurrentMaxScale = Math.max(  
  37.                 MIN_ZOOM_SCALE,  
  38.                 4 * Math.min(FLOAT_TYPE * mImageHeight / mSurfaceHeight, 1.0f  
  39.                         * mImageWidth / mSurfaceWidth));  
  40.         mCurrentScale = MIN_ZOOM_SCALE;  
  41.         mCenterX = mImageWidth / 2;  
  42.         mCenterY = mImageHeight / 2;  
  43.         calcRect();  
  44.   
  45.     }  
  46.   
  47.     private void adjustCenter() {  
  48.         int w = mRectSrc.right – mRectSrc.left;  
  49.         int h = mRectSrc.bottom – mRectSrc.top;  
  50.   
  51.         if (mCenterX – w / 2 < 0) {  
  52.             mCenterX = w / 2;  
  53.             mRectSrc.left = 0;  
  54.             mRectSrc.right = w;  
  55.         } else if (mCenterX + w / 2 >= mImageWidth) {  
  56.             mCenterX = mImageWidth – w / 2;  
  57.             mRectSrc.right = mImageWidth;  
  58.             mRectSrc.left = mRectSrc.right – w;  
  59.   
  60.         } else {  
  61.             mRectSrc.left = mCenterX – w / 2;  
  62.             mRectSrc.right = mRectSrc.left + w;  
  63.         }  
  64.   
  65.         if (mCenterY – h / 2 < 0) {  
  66.             mCenterY = h / 2;  
  67.             mRectSrc.top = 0;  
  68.             mRectSrc.bottom = h;  
  69.         } else if (mCenterY + h / 2 >= mImageHeight) {  
  70.             mCenterY = mImageHeight – h / 2;  
  71.             mRectSrc.bottom = mImageHeight;  
  72.             mRectSrc.top = mRectSrc.bottom – h;  
  73.         } else {  
  74.             mRectSrc.top = mCenterY – h / 2;  
  75.             mRectSrc.bottom = mRectSrc.top + h;  
  76.         }  
  77.   
  78.     }  
  79.   
  80.     private void calcRect() {  
  81.         int w, h;  
  82.         float imageRatio, surfaceRatio;  
  83.         imageRatio = FLOAT_TYPE * mImageWidth / mImageHeight;  
  84.         surfaceRatio = FLOAT_TYPE * mSurfaceWidth / mSurfaceHeight;  
  85.   
  86.         if (imageRatio < surfaceRatio) {  
  87.             h = mSurfaceHeight;  
  88.             w = (int) (h * imageRatio);  
  89.         } else {  
  90.             w = mSurfaceWidth;  
  91.             h = (int) (w / imageRatio);  
  92.         }  
  93.   
  94.         if (mCurrentScale > MIN_ZOOM_SCALE) {  
  95.             w = Math.min(mSurfaceWidth, (int) (w * mCurrentScale));  
  96.             h = Math.min(mSurfaceHeight, (int) (h * mCurrentScale));  
  97.         } else {  
  98.             mCurrentScale = MIN_ZOOM_SCALE;  
  99.         }  
  100.   
  101.         mRectDes.left = (mSurfaceWidth – w) / 2;  
  102.         mRectDes.top = (mSurfaceHeight – h) / 2;  
  103.         mRectDes.right = mRectDes.left + w;  
  104.         mRectDes.bottom = mRectDes.top + h;  
  105.   
  106.         float curImageRatio = FLOAT_TYPE * w / h;  
  107.         int h2, w2;  
  108.         if (curImageRatio > imageRatio) {  
  109.             h2 = (int) (mImageH eight / mCurrentScale);  
  110.             w2 = (int) (h2 * curImageRatio);  
  111.         } else {  
  112.   
  113.             w2 = (int) (mImageWidth / mCurrentScale);  
  114.             h2 = (int) (w2 / curImageRatio);  
  115.         }  
  116.         mRectSrc.left = mCenterX – w2 / 2;  
  117.         mRectSrc.top = mCenterY – h2 / 2;  
  118.         mRectSrc.right = mRectSrc.left + w2;  
  119.         mRectSrc.bottom = mRectSrc.top + h2;  
  120.     }  
  121.   
  122.     public void setMaxZoom(float value) {  
  123.         mCurrentMaxScale = value;  
  124.     }  
  125.   
  126.     public void setBitmap(Bitmap b) {  
  127.   
  128.         if (b == null) {  
  129.             return;  
  130.         }  
  131.         synchronized (MySurfaceView3.class) {  
  132.             mBitmap = b;  
  133.             if (mImageHeight != mBitmap.getHeight()  
  134.                     || mImageWidth != mBitmap.getWidth()) {  
  135.                 mImageHeight = mBitmap.getHeight();  
  136.                 mImageWidth = mBitmap.getWidth();  
  137.                 init();  
  138.             }  
  139.             showBitmap();  
  140.         }  
  141.   
  142.     }  
  143.   
  144.     private void showBitmap() {  
  145.         synchronized (MySurfaceView3.class) {  
  146.             Canvas c = getHolder().lockCanva s();  
  147.             if (c != null && mBitmap != null) {  
  148.                 c.drawColor(Color.GRAY);  
  149.                 c.drawBitmap(mBitmap, mRectSrc, mRectDes, null);  
  150.                 getHolder().unlockCanvasAndPost(c);  
  151.             }  
  152.         }  
  153.     }  
  154.   
  155.     private void dragAction(MotionEvent event) {  
  156.   
  157.         synchronized (MySurfaceView3.class) {  
  158.             PointF currentPoint = new PointF();  
  159.             currentPoint.set(event.getX(), event.getY());  
  160.             int offsetX = (int) currentPoint.x – (int) mStartPoint.x;  
  161.             int offsetY = (int) currentPoint.y – (int) mStartPoint.y;  
  162.             mStartPoint = currentPoint;  
  163.   
  164.             mCenterX -= offsetX;  
  165.             mCenterY -= offsetY;  
  166.   
  167.             adjustCenter();  
  168.             showBitmap ();  
  169.         }  
  170.     }  
  171.   
  172.     private void zoomAcition(MotionEvent event) {  
  173.   
  174.         synchronized (MySurfaceView3.class) {  
  175.   
  176.             float newDist = spacing(event);  
  177.             float scale = newDist / mStartDistance;  
  178.             mStartDistance = newDist;  
  179.   
  180.             mCurrentScale *= scale;  
  181.             mCurrentScale = Math.max(FLOAT_TYPE,  
  182.                     Math.min(mCurrentScale, mCurrentMaxScale));  
  183.   
  184.             calcRect();  
  185.             adjustCenter();  
  186.             showBitmap();  
  187.         }  
  188.     }  
  189.   
  190.     @Override  
  191.     public boolean onTouch(View v, MotionEvent event) {  
  192.   
  193.         switch (event.getAction() & MotionEvent.ACTION_MASK) {  
  194.         case MotionEvent.ACTION_DOWN:  
  195.             mStartPoint.set(event.getX(), event.getY());  
  196.             mStatus = DRAG;  
  197.             break;  
  198.   
  199.         case MotionEvent.ACTION_POINTER_DOWN:  
  200.             float distance = spacing(event);  
  201.             if (distance > 10f) {  
  202.   
  203.                 mStatus = ZOOM;  
  204.                 mStartDistance = distance;  
  205.             }  
  206.   
  207.             break;  
  208.   
  209.         case MotionEvent.ACTION_MOVE:  
  210.             if (mStatus == DRAG) {  
  211.                 dragAction(event);  
  212.             } else {  
  213.   
  214.                 if (event.getPointerCount() == 1)  
  215.                     return true;  
  216.                 zoomAcition(event);  
  217.             }  
  218.             break;  
  219.         case MotionEvent.ACTION_UP:  
  220.         case MotionEvent.ACTION_POINTER_UP:  
  221.             mStatus = NONE;  
  222.             break;  
  223.         default:  
  224.             break;  
  225.         }  
  226.   
  227.         return true;  
  228.     }  
  229.   
  230.     private float spacing(MotionEvent event) {  
  231.         float x = event.getX(0) – event.getX(1);  
  232.         float y = event.getY(0) – event.getY(1);  
  233.         return (float) Math.sqrt(x * x + y * y);  
  234.     }  
  235.   
  236.     @Override  
  237.     public void surfaceCreated(SurfaceHolder holder) {  
  238.         // TODO Auto-generated method stub  
  239.     }  
  240.   
  241.     // 初始化  
  242.     @Override  
  243.     public void surfaceChanged(SurfaceHolder holder, int format, int width,  
  244.             int height) {  
  245.   
  246.         synchronized (MySurfaceView3.class) {  
  247.             mRectDes.set(00, width, height);  
  248.             mSurfaceHeight = height;  
  249.             mSurfaceWidth = width;  
  250.             init();  
  251.             if (mBitmap != null) {  
  252.                 showBitmap();  
  253.             }  
  254.         }  
  255.     }  
  256.   
  257.     @Override  
  258.     public void surfaceDestroyed( SurfaceHolder holder) {  
  259.   
  260.     }  
  261.   
  262. }  

[java]  view plain  copy

  在CODE上查看代码片 派生到我的代码片

[java]  view plain  copy

  在CODE上查看代码片 派生到我的代码片

Leave a Comment

Your email address will not be published.