私はベクトル描画アプリケーションを作成中ですが、これを正しく行うのは簡単な作業ではなく、かなりの作業が必要です。
留意すべきいくつかの問題:
- ベクター グラフィックスを使用していない場合 (たとえば、CGPath はベクターです)、ピクセレーションを削除することはできません。たとえば、UIImage の解像度はそれほど大きくありません。
- 描画がピクセル化されないようにするには、すべてを再描画する必要があります。大量の描画がある場合、これは実行するのにコストのかかる作業になる可能性があります。
- 過度に大きなコンテキストが必要になり、描画がデバイスの能力を超える可能性があるため、ズーム中に良好な解像度を持つことはほとんど不可能です
私はコア グラフィックスを使用して描画を行っているため、複数の CGContext を割り当てて管理し、それらをバッファーとして使用することで、この問題を解決しました。常に最小ズーム レベル (倍率 1) で保持されているコンテキストが 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 に従い、現在のズームと変換に基づいて新しい描画をスケーリングするなど、これは山のようなタスクです。うまくいけば、これがあなたのやる気を起こさせ、あなたを正しい軌道に乗せるか、そのピクセル化を取り除くことは努力する価値がないと判断するでしょう:)