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

For*_*ine 12 java android drawing canvas zooming

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

除了缩放/平移之外,路径部分的整个绘制都可以.

当对白板应用变焦时,无论我采用何种方式,应用变焦后的所有线条都会相对于我实际上进行了抚摸的位置而移位.

我会尝试尽可能好地公开细节,而不会显示不必要的代码,仍然是一个很长的帖子,拜托,请耐心等待.

由于图像胜过千言万语,我将说明情况:

在此输入图像描述

在此输入图像描述

在此输入图像描述

在此输入图像描述

所以,我尝试了很多不同的方法,没有任何成功.

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

它实现了扩展View.

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

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

    if(isDrawing)
    {
        canvas.drawPath(mPath,  mPaint);
        canvas.drawBitmap(mBitmap, 0, 0, mPaint);   
    }
}
Run Code Online (Sandbox Code Playgroud)

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

 <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" />
Run Code Online (Sandbox Code Playgroud)

将某些内容绘制到画布后,我将给定的位图发送到我的视图,然后清理画布以将其全新设置为更多图形:

 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();  


 }
Run Code Online (Sandbox Code Playgroud)

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

在onScale的时刻,我告诉我的画布我的scalling比例是多少:

@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;
}
Run Code Online (Sandbox Code Playgroud)

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

    mView.setScaleX(factor);
    mView.setScaleY(factor);     
Run Code Online (Sandbox Code Playgroud)

现在,对于最重要的部分,在onScaleEnd上,我调用一个方法,我尝试获取当前的画布位图并将其发送到我的视图,以便与其兄弟姐妹和平相处,每个兄弟都有自己的大小和偏移量.

    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);
    }
Run Code Online (Sandbox Code Playgroud)

现在,我已经尝试过直接显示在画布上的所有东西,给它一个缩放/翻译量; 尝试单独使用位图工作,然后将它们发送回新的干净画布.

在应用了一定量的ZOOM之后,我仍然会在我的笔画上得到那个位移!我只想画画; 给它一个缩放; 然后画出更多的东西,让笔画留在我画的地方!

那可能吗?

我刚刚玩S Note应用程序,它正是我想要实现的目标.

Ole*_* K. 5

我想为你提出一些解决方案,但我不确定它会起作用.

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

     tempBmp = Bitmap.createScaledBitmap(previousBmp,
        (int)(mView.getWidth()*scaleFactor),
        (int)(mView.getHeight()*scaleFactor), true);
Run Code Online (Sandbox Code Playgroud)

我们假设你有一个平板电脑,1280x800像素和比例因子4x甚至10x.您将尝试相应地分配16Mb40Mb位图!

它很容易被OutOfMemoryError扔到这里,所以你需要在概念上使用另一种方法.

我建议你Picture上课.

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

我没有尝试这个解决方案,但我希望Picture课程能帮到你.

  • 嘿@Olekssi Kropachov,非常感谢你的帮助.我要尝试一下,然后我会告诉你它是否有效.我不熟悉那个Picture类,看起来合法!并感谢有关图像大小调整的建议! (2认同)