4

我正在寻找一种解决方案,以便在绘图视图上进行漂亮的缩放。在我的应用程序中,我有一个带有其他 UIView 的视图(用作绘图视图),当我在其上绘制笔画时,笔画是完美的。但是当我放大视图时,我有这个非常丑陋的效果(像素化的笔画):(来源:imagup.com截屏

网址图片

是否有解决方案才能获得适当的中风?

我的 UIViewController 有这样的层次结构:

  • UIViewController
    • 滚动视图
      • 可缩放视图(使用 viewForZoomingInScrollView 方法定义)
        • 图像视图
        • 图纸视图

非常感谢 !

问候,塞巴斯蒂安;)

4

3 回答 3

4

我正在制作矢量绘图应用程序,让我告诉你,要正确完成这不是一项简单的任务,需要相当多的工作。

需要记住的一些问题:

  • 如果您不使用矢量图形(例如,CGPath 是矢量),您将无法移除像素化。例如,一个 UIImage 就只有这么多的分辨率。
  • 为了使您的绘图看起来不像素化,您将不得不重绘所有内容。如果你有很多绘图,这可能是一项昂贵的任务。
  • 具有良好的分辨率而缩放几乎是不可能的,因为它需要过大的上下文,并且您的绘图可能会超出设备的功能

我使用核心图形进行绘图,因此我解决此问题的方法是分配和管理多个 CGContext 并将它们用作缓冲区。我有一个上下文始终保持在我的最小缩放级别(比例因子为 1)。该上下文始终被引入并使其在完全取消缩放时不会花费时间重新绘制,因为它已经完成了。缩放时单独使用另一个上下文进行绘图。未缩放时,该上下文将被忽略(因为无论如何都必须根据新的缩放级别重新绘制它)。我如何执行缩放的高级算法如下:

- (IBAction)handlePinchGesture:(UIGestureRecognizer *)sender
{
    if(sender.state == UIGestureRecognizerStateBegan)
    {
         //draw an image from the unzoomedContext into my current view

             //set the scale transformation of my current view to be equal to "currentZoom", a property of the view that keeps track of the actual zoom level
    }
    else if(sender.state == UIGestureRecognizerStateChanged)
    {
         //determine the new zoom level and transform the current view, keeping track in the currentZoom property

             //zooming will be pixelated.
    }
    else if(sender.state == UIGestureRecognizerStateEnded || sender.state == UIGestureRecognizerStateCancelled)
    {
             if(currentZoom == 1.0)
             {
                   //you are done because the unzoomedContext image is already drawn into the view!
             }
             else
             {
                   //you are zoomed in and will have to do special drawing

                   //perform drawing into your zoomedContext
                   //scale the zoomedContext

                   //set the scale of your current view to be equal to 1.0

                   //draw the zoomedContext into the current view.  It will not be pixelated!

                   //any drawing done while zoomed needs to be "scaled" based on your current zoom and translation amounts and drawn into both contexts
             }

    }

}

这对我来说变得更加复杂,因为我有额外的缓冲区用于缓冲区,因为在有大量绘图时绘制路径的图像比绘制路径要快得多。

在管理多个上下文、调整代码以有效地绘制到多个上下文、遵循适当的 OOD、根据当前缩放和平移缩放新绘图等之间,这是一项艰巨的任务。希望这可以激励您并使您走上正确的轨道,或者您认为摆脱这种像素化不值得努力:)

于 2012-08-28T14:59:10.457 回答
1

我遇到了同样的问题并找到了解决方案:告诉视图使用 aCATiledLayer作为支持层,然后告诉视图它支持多少级别的缩放。这对我有用,当(父)视图缩放时,我的绘图方法会自动调用。

levelsOfDetail和的简短解释levelsOfDetailBias

  • levelsOfDetail确定总共有多少缩放级别
  • levelsOfDetailBias确定其中有多少正在放大。

所以在我的示例中,我有 4 个缩放级别,3 个被放大,1 个是非缩放级别,这意味着我的视图仅在放大时重绘。

@imprementation MyZoomableView

+ (Class)layerClass
{
    return [CATiledLayer class];
}


- (id)initWithFrame:(CGRect)frame
{
    if ((self = [super initWithFrame:frame])) {
        ((CATiledLayer *)self.layer).levelsOfDetail = 4;
        ((CATiledLayer *)self.layer).levelsOfDetailBias = 3;
    }
    return self;
}

@end
于 2012-10-02T06:33:48.913 回答
0

[self setContentScaleFactor:scale];在您的scrollViewDidEndZooming:委托方法中使用。

于 2013-05-14T10:30:48.417 回答