java - Android Canvas,具有不同缩放量的多个路径

标签 java android canvas drawing zooming

它应该是一种简单的白板工具,具有缩放/平移效果。

路径部分的整个绘图都没有问题,除了涉及缩放/平移的时候。

当对白板应用缩放时,无论我采用何种方式,应用缩放后出现的所有线条都会相对于我实际进行描边的位置发生位移。

我会尽量公开细节,不显示不必要的代码,仍然是一篇很长的文章,请耐心等待。

一图胜一千,我来举例说明一下:

enter image description here

enter image description here

enter image description here

enter image description here

所以,我尝试了很多不同的方法,但都没有成功。

现在回到技术部分,这就是我现在正在做的:

实现了扩展View。

我只使用 onDraw 方法来执行正在应用的笔画的“动画”:

@Override
public void onDraw(Canvas canvas) 
{
    super.onDraw(canvas);

    if(isDrawing)
    {
        canvas.drawPath(mPath,  mPaint);
        canvas.drawBitmap(mBitmap, 0, 0, mPaint);   
    }
}

我有两个 ImageView,用于在执行绘图和缩放后立即放置生成的位图。我使用两个 View 的原因是交换它们,以便在绘图渲染时刻始终有一个可用 View 。

 <ImageView
 android:id="@+id/imageView"
 android:layout_width="match_parent"
 android:layout_height="match_parent"
 android:layout_alignParentLeft="true"  
 android:layout_alignParentTop="true"    
 android:visibility="visible"     
 android:scaleType="matrix" />

 <ImageView     
 android:id="@+id/imageView2"
 android:layout_width="match_parent"
 android:layout_height="match_parent"
 android:layout_alignParentLeft="true"          
 android:layout_alignParentTop="true"    
 android:visibility="visible"     
 android:scaleType="matrix" />

在 Canvas 上绘制了一些东西后,我将给定的位图发送到我的 View ,然后清理 Canvas 以将其设置为全新以供更多绘图使用:

 private void sendImage2BackView()
 {
     //veeery extensive and boring code surpressed here

     //set the entire hocus-pocus' resulting bitmap as a resource for my view
     mView.setImageBitmap(tempBmp);
     mView.bringToFront();  


 }

我实现了一个扩展 ScaleGestureDetector.SimpleOnScaleGestureListener 的 ScaleListener 类

在 onScale 时刻,我告诉 Canvas 我的缩放比例是多少:

@Override
public boolean onScale(ScaleGestureDetector detector) 
{   
    drawAction = ZOOM;      
    scaleFactor *= detector.getScaleFactor();
    scaleFactor = Math.max(MIN_ZOOM, Math.min(scaleFactor, MAX_ZOOM));

    canvas.setScaleFactor(scaleFactor);
    return true;
}

然后,在我的 View (canvas obj) 中,我只是将比例设置为正在使用的 View :

    mView.setScaleX(factor);
    mView.setScaleY(factor);     

现在,对于最重要的部分,在 onScaleEnd,我调用了一个方法,我尝试按原样获取当前 Canvas 位图并将其发送到我的 View 以与其 sibling 和平相处,每个 sibling 都有自己的大小和偏移量.

    public void setScaleEnd()
    {
         //Lots of more boring code surpressed here
         //....

         //I store the bitmap that was contained at the ImageView
         // IF anyone is present
         previousBmp = ((BitmapDrawable)mView.getDrawable()).getBitmap();

         //then, I create a brand new scaled bitmap,in order to 
         // acquire the same proportion of ZOOM that I've just applied
         tempBmp = Bitmap.createScaledBitmap(previousBmp,
            (int)(mView.getWidth()*scaleFactor),
            (int)(mView.getHeight()*scaleFactor), true);


         int height = (int)(mView.getHeight()*scaleFactor);
         int width = (int)(mView.getWidth()*scaleFactor);

         //set my matrix
         mMatrix = new Matrix();

         //give it the right proportion
         mMatrix.postScale(scaleFactor, scaleFactor);

         translationX = mView.getWidth() / 2 - width / 2;
         translationY = mView.getHeight() / 2 - height / 2;

         //give it some necessary translation amount
         mMatrix.postTranslate(translationX, translationY);

         //set the matrix to the view, and send the resized bitmap to my ImageView.
         mView.setImageMatrix(mMatrix);
         mView.setImageBitmap(tempBmp);
    }

现在,我已经尝试过直接在 Canvas 上展示的所有内容,给它一个缩放/平移量;尝试单独处理位图,然后将它们发送回新的干净 Canvas 。

在应用一定量的 ZOOM 后,我的笔画仍然会出现这种位移!!! 我只想画画;放大它;然后再画一些东西,让笔画留在我画的地方!

这可能吗?

我只是在玩 S Note 应用程序,它完全符合我的要求。

最佳答案

我想向您提出一些解决方案,但我不确定它是否有效。

首先我需要澄清一下,你在这段代码中犯了一个大错误:

     tempBmp = Bitmap.createScaledBitmap(previousBmp,
        (int)(mView.getWidth()*scaleFactor),
        (int)(mView.getHeight()*scaleFactor), true);

假设您的平板电脑具有 1280x800 像素和比例因子 4x 甚至 10x。您将尝试相应地分配 16Mb40Mb 位图!

很容易在此处抛出 OutOfMemoryError,因此您需要在概念上使用另一种方法。

我建议你使用 Picture类。

  1. 您需要确定向用户提供哪种尺寸的原始图片?
  2. 之后,您需要使用方法Picture.beginRecord(int width, int height) 在图片周围创建Canvas 对象。
  3. 现在您可以应用比例因子、平移 Canvas 并执行绘图操作。
  4. onDraw() 方法中,您需要使用方法Picture.draw(Canvas canvas) 绘制图片。将相应的设置(比例因子、翻译)应用于 Canvas 。

我没有尝试过这个解决方案,但我希望 Picture 类对您有所帮助。

关于java - Android Canvas,具有不同缩放量的多个路径,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26391911/

相关文章:

java - 比较Java中的List元素

java - 您能指导我代码中有什么问题吗?

java - 如何在位图 Java 中创建文本周围的轮廓

安卓远程登录教程

javascript - 为什么这个 random() 分布看起来不对称?

java - 架构 'SA' 不存在并删除表

java - 如何让java中的Generic Object实现一个接口(interface)

javascript - React native - Android - 警告对话框可取消 false 不工作

html - 为什么 Google Images 使用 Canvas 绘制图像?

javascript - HTML5 Canvas 动画不显示背景图像