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

时间:2014-10-15 20:53:14

标签: java android canvas drawing zooming

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

除了缩放/平移之外,路径部分的整个绘制都没有问题。

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

我会尝试尽可能详细地公开细节,而不会显示不必要的代码,仍然是相当长的帖子,请耐心等待。

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

enter image description here

enter image description here

enter image description here

enter image description here

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

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

实施了扩展视图。

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

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

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

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

 <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" />

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

 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片刻期间,我告诉我的画布我的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;
}

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

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

现在,对于最重要的部分,在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);
    }

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

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

这可能吗?

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

1 个答案:

答案 0 :(得分:5)

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

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

     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)
  3. 在图片周围创建Canvas对象
  4. 现在,您可以应用比例因子,翻译画布并执行绘图操作。
  5. onDraw()方法中,您需要使用方法Picture.draw(Canvas canvas)绘制图片,并将相应的设置(比例因子,平移)应用于画布。
  6. 我没有尝试这个解决方案,但我希望Picture课程会帮助你。