zoukankan      html  css  js  c++  java
  • Android Bitmap上绘制Bitmap

       先说下我要解决的问题,如图,界面上的小图片能够随意拖动,背景的大图片可以放大(超过屏幕)也可以随意拖动,我现在要做的是将小图片的位置记录下来,放大大图片里形成一张新的图片而且要保证两张图片的相对位置和大小保持不变,花点时间实现这个效果:

     

      1.背景图片的放大可拖动我使用的是Google提供的PhototView开源包,就在再这里展示了;

      2.小图片的随意拖动,这个相信对大家来说都不是大问题,我附上自己写的,参考下:

    package com.example.androidhtmldemo;
    
    import android.app.Activity;
    import android.util.DisplayMetrics;
    import android.view.MotionEvent;
    import android.view.View;
    import android.view.View.OnTouchListener;
    
    /**
     * View随手势在屏幕上移动
     * @author Administrator
     *
     */
    public class OnViewMoveTouchListener implements OnTouchListener {
        private View imgView;
        private int lastX,lastY;
        private int left,right,top,bottom;
        private DisplayMetrics dm;
        public OnViewMoveTouchListener(View v,Activity context) {
            this.imgView = v;
            dm = context.getResources().getDisplayMetrics();;
        }
        
        
        
        @Override
        public boolean onTouch(View v, MotionEvent event) {
    
            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);
                int dy = (int) (event.getRawY() - lastY);
    
                left = v.getLeft() + dx;
                right = v.getRight() + dx;
                top = v.getTop() + dy;
                bottom = v.getBottom() + dy;
    
                if (left < 0) {
                    left = 0;
                    right = left + v.getWidth();
                }
                if (right > dm.widthPixels) {
                    right = dm.widthPixels;
                    left = dm.widthPixels - v.getWidth();
                }
                if (top < 0) {
                    top = 0;
                    bottom = dm.heightPixels + v.getHeight();
                }
                if (bottom > dm.heightPixels) {
                    bottom = dm.heightPixels;
                    top = dm.heightPixels - v.getHeight();
                }
                imgView.layout(left, top, right, bottom);
                lastX = (int) event.getRawX();
                lastY = (int) event.getRawY();
                break;
            case MotionEvent.ACTION_UP:
                break;
            }
            return true;
        }
    }

      3.相关方法:

      ①RectF mRect = mPhotoView.getDisplayRect();  这里获取的是图片占据的矩形,可以获取矩形四个角的坐标,当然获取的值是相对于我们应用在屏幕上占据的空间如果超出屏幕会获取负值

      ②mCanvas.drawBitmap(bitmap, left, top, paint);  bitmap:要在画布上绘制的图片,left:在画布上绘制图片X起点;Top:在画布上绘制图片的Y起点;paint画笔,可以为null;

      ③ mCanvas.drawBitmap(bitmap, src, dst, paint);bitmap:在要画布上绘制的Bitmap,src:bitmap在画布上占据的矩形,dst:这个是Bitmap在画布上占据的矩形和位置,我解释的可能不太清楚(简单的说:src就是说明这个Bitmap需要多大的空间,当然如果这个空间小于位图的尺寸,位图只会显示一部分,具体显示哪一部分可以调整这个Rect来获取;dst:这个标示要把Bitmap绘制在画布上的哪个位置),可以参考下下面代码:

    Rect mSrcRect = new Rect(0, 0, dpDrawable.getWidth(), dpDrawable.getHeight()); 
    Rect mDstRect = new Rect((int)x, (int)y, (int)(x + width), (int)(y + height));

     4.相关代码:

    package com.example.androidhtmldemo;
    
    import android.content.Context;
    import android.graphics.Bitmap;
    import android.graphics.Bitmap.Config;
    import android.graphics.BitmapFactory;
    import android.graphics.Canvas;
    import android.graphics.Rect;
    import android.util.Log;
    
    public class DrawBpOnBpUtils {
        private Context context;
        private Bitmap bgDrawable, dpDrawable;
        private int bgDrawableId,dpDrawableId;
        /**
         * 
         * @param context 上下文环境
         * @param bgDrawableId  背景图片
         * @param dpDrawableId  印章
         */
        public DrawBpOnBpUtils(Context context, int bgDrawableId, int dpDrawableId) {
            this.context = context;
            this.bgDrawableId = bgDrawableId;
            this.dpDrawableId = dpDrawableId;
        }
        
        /**
    *画布上能分配给Bitmap的空间是有限的,为了让图片全部显示就对图片做适当的压缩
    * @param drawableId * @param scale 图片相对比例 * @return */ private Bitmap getBitmapByBitmap(int drawableId,float width,float height) { int simpleSize = 1 ; BitmapFactory.Options options = new BitmapFactory.Options(); options.inJustDecodeBounds = true; BitmapFactory.decodeResource(context.getResources(), drawableId,options); while ((options.outWidth / simpleSize > width) || (options.outHeight / simpleSize > height)) { simpleSize *= 2; } options.inJustDecodeBounds = false; options.inSampleSize = simpleSize; return BitmapFactory.decodeResource(context.getResources(), drawableId); } /** * 绘制图片 * @param scale 两张Bitmap相对比例 * @param x dpDrawable在canvas的 left * @param y dpDrawable在canvase的 top * @return */ public Bitmap onDrawBitmap(float width,float height,float x,float y){ bgDrawable = BitmapFactory.decodeResource(context.getResources(), bgDrawableId); dpDrawable = getBitmapByBitmap(dpDrawableId, width,height); Bitmap result = Bitmap.createBitmap(bgDrawable.getWidth(), bgDrawable.getHeight(), Config.ARGB_8888); Rect mSrcRect = new Rect(0, 0, dpDrawable.getWidth(), dpDrawable.getHeight()); Rect mDesRect = new Rect((int)x, (int)y, (int)(x + width), (int)(y + height)); Canvas mCanvas = new Canvas(result); mCanvas.drawBitmap(bgDrawable, 0, 0, null); mCanvas.drawBitmap(dpDrawable, mSrcRect, mDesRect, null); Log.e(getClass().getName(), "x:" + x + ";y:" + y + ";top:" + (x + dpDrawable.getWidth()) + "right:" + (y + dpDrawable.getHeight())); bgDrawable.recycle(); dpDrawable.recycle(); bgDrawable = null; dpDrawable = null; return result; } }
    package com.example.androidhtmldemo;
    
    
    import uk.co.senab.photoview.PhotoView;
    import android.app.Activity;
    import android.graphics.Bitmap;
    import android.graphics.BitmapFactory;
    import android.graphics.RectF;
    import android.os.Bundle;
    import android.util.Log;
    import android.view.View;
    import android.view.View.OnClickListener;
    import android.view.Window;
    import android.widget.Button;
    
    import com.example.androidhtmldemo.OnViewMoveTouchListener.OnViewMoveRsultCallback;
    
    public class ShowPhotoActivity extends Activity{
        private PhotoView mPhotoView;
        private PhotoView imgSeal;
        private Button btnTakePhoto;
        private Bitmap newBitmap;
        private float newLeft = 0;
        private float newTop = 0;
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            requestWindowFeature(Window.FEATURE_NO_TITLE);
            setContentView(R.layout.activity_showphoto);
            mPhotoView = (PhotoView) findViewById(R.id.photoView1);
            imgSeal = (PhotoView) findViewById(R.id.imgPutSeal);
            btnTakePhoto = (Button) findViewById(R.id.btnTakePhoto);
            OnViewMoveTouchListener onTouchListener = new OnViewMoveTouchListener(imgSeal, this);
         //imgSeal是可以随意拖动的,尝试获取他的坐标结果都不太满意,只好做一个回调让结果返回到这里(汗颜) onTouchListener.setOnViewMoveRsultCallback(
    new OnViewMoveRsultCallback() { @Override public void onViewMoveResultCallback(float left, float top, float right, float bottom) { newLeft = left; newTop = top; } }); imgSeal.setOnTouchListener(onTouchListener); imgSeal.setDrawingCacheEnabled(true); btnTakePhoto.setOnClickListener(new OnClickListener() { @Override public void onClick(View arg0) { drawBitmap(newLeft,newTop); } }); } /** * * @param left 印章 left * @param top 印章 Top */ private void drawBitmap(float left,float top){ if(newBitmap != null){ newBitmap.recycle(); newBitmap = null; } Log.e(getPackageName(), "newLeft:" + newLeft + ";newTop:" + newTop); RectF mRect = mPhotoView.getDisplayRect(); float x = left; float y = top; if(mRect.left < 0){ x += Math.abs(mRect.left); } if(mRect.top < 0){ y += Math.abs(mRect.top); } if(mRect.left > 0){ x -= mRect.left; } if(mRect.top > 0){ y -= mRect.top; } BitmapFactory.Options options = new BitmapFactory.Options(); options.inJustDecodeBounds = false; Bitmap bp = BitmapFactory.decodeResource(getResources(), R.drawable.img_test,options); float scale = bp.getWidth() / mRect.width(); //原图的宽与有效区域宽的比值 bp.recycle(); bp = null; newBitmap = new DrawBpOnBpUtils(this, R.drawable.img_test, R.drawable.images) .onDrawBitmap(imgSeal.getWidth() * scale,imgSeal.getHeight() * scale, x * scale,y * scale); mPhotoView.setImageBitmap(newBitmap); } }

     附上布局:

    <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical" >
    
        <uk.co.senab.photoview.PhotoView
            android:id="@+id/photoView1"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:layout_gravity="center_horizontal"
            android:adjustViewBounds="true"
            android:src="@drawable/img_test" />
    
        <uk.co.senab.photoview.PhotoView
            android:id="@+id/imgPutSeal"
            android:layout_width="48dp"
            android:layout_height="48dp"
            android:adjustViewBounds="true"
            android:src="@drawable/images" />
    
        <Button
            android:id="@+id/btnTakePhoto"
            android:layout_width="96dp"
            android:layout_height="48dp"
            android:layout_alignParentBottom="true"
            android:layout_centerHorizontal="true"
            android:text="快照" />
    
    </RelativeLayout>

    还要需要改进的地方:①imgSeal的大小可以随着mPhotoView的大小和位置而改变②之后生成新图片应该根据背景图片的大小和位置来显示,欢迎大家交流

      

  • 相关阅读:
    Pizza Pie Charts – 基于 Snap SVG 框架的响应式饼图
    超好玩!10款神奇的字符图案 & 词汇云生成工具
    『摄影欣赏』15幅迷人的来自世界各地的婴儿照片【组图】
    CSS 魔法系列:纯 CSS 绘制图形(各种形状的钻石)
    【特别推荐】10款唯美浪漫的婚礼 & 结婚纪念网站模板
    25款创新的 PSD 格式搜索框设计素材【免费下载】
    时尚前沿:15个创意的 3D 字体设计艺术作品欣赏
    Resumable.js – 基于 HTML5 File API 的文件上传
    经典设计:17个最有效的学习着陆页设计的例子
    图标集锦:10套免费的社交媒体 & 社交网站图标
  • 原文地址:https://www.cnblogs.com/ZhangXiangQian/p/4942189.html
Copyright © 2011-2022 走看看