簡體   English   中英

旋轉UIImageView的任何快速和臟的抗鋸齒技術?

[英]Any quick and dirty anti-aliasing techniques for a rotated UIImageView?

我有一個UIImageView(全幀和矩形),我正在用CGAffineTransform旋轉。 UIImageView的UIImage填充整個幀。 旋轉和繪制圖像時,邊緣會出現明顯的鋸齒狀。 有什么我可以做的讓它看起來更好嗎? 顯然沒有背景消除鋸齒。

默認情況下,iOS上CoreAnimation圖層的邊緣不會被抗鋸齒。 但是,您可以在Info.plist中設置一個鍵,以啟用邊緣的抗鋸齒:UIViewEdgeAntialiasing。

https://developer.apple.com/library/content/documentation/General/Reference/InfoPlistKeyReference/Articles/iPhoneOSKeys.html

如果您不希望啟用此選項的性能開銷,則解決方法是在圖像邊緣周圍添加1px透明邊框 這意味着圖像的“邊緣”不再位於邊緣,因此不需要特殊處理!

新API - iOS 6/7

同樣適用於iOS 6,如@Chris所述,但直到iOS 7才公開。

從iOS 7開始,CALayer有一個新屬性allowsEdgeAntialiasing ,在這種情況下完全符合您的要求,而不會產生為應用程序中的所有視圖啟用它的開銷! 這是CALayer的屬性,因此要為UIView啟用此功能,請使用myView.layer.allowsEdgeAntialiasing = YES

只需為圖像添加1px透明邊框即可

CGRect imageRect = CGRectMake(0, 0, image.size.width, image.size.height);
UIGraphicsBeginImageContextWithOptions(imageRect.size, NO, 0.0);
[image drawInRect:CGRectMake(1,1,image.size.width-2,image.size.height-2)];
image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();

請記住設置適當的反別名選項:

CGContextSetAllowsAntialiasing(theContext, true);
CGContextSetShouldAntialias(theContext, true);

只需在plist中添加“帶邊緣抗鋸齒渲染”和YES,它就能工作。

我完全推薦以下庫。

http://vocaro.com/trevor/blog/2009/10/12/resize-a-uiimage-the-right-way/

它包含許多有用的UIImage擴展,可以解決這個問題,還包括生成縮略圖等的代碼。

請享用!

我發現具有平滑邊緣和清晰圖像的最佳方法是:

CGRect imageRect = CGRectMake(0, 0, self.photo.image.size.width, self.photo.image.size.height);
UIGraphicsBeginImageContextWithOptions(imageRect.size, NO, 0.0);
[self.photo.image drawInRect:CGRectMake(1, 1, self.photo.image.size.width - 2, self.photo.image.size.height - 2)];
self.photo.image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();

像某些人描述的那樣添加Info.plist鍵會對性能造成很大影響,如果你使用它,那么你基本上將它應用於所有內容而不僅僅是你需要它的地方。

另外,不要只使用UIGraphicsBeginImageContext(imageRect.size); 否則該層將模糊。 你必須像我所示的那樣使用UIGraphicsBeginImageContextWithOptions

我從這里找到了這個解決方案,它很完美:

+ (UIImage *)renderImageFromView:(UIView *)view withRect:(CGRect)frame transparentInsets:(UIEdgeInsets)insets {
    CGSize imageSizeWithBorder = CGSizeMake(frame.size.width + insets.left + insets.right, frame.size.height + insets.top + insets.bottom);
    // Create a new context of the desired size to render the image
    UIGraphicsBeginImageContextWithOptions(imageSizeWithBorder, NO, 0);
    CGContextRef context = UIGraphicsGetCurrentContext();

    // Clip the context to the portion of the view we will draw
    CGContextClipToRect(context, (CGRect){{insets.left, insets.top}, frame.size});
    // Translate it, to the desired position
    CGContextTranslateCTM(context, -frame.origin.x + insets.left, -frame.origin.y + insets.top);

    // Render the view as image
    [view.layer renderInContext:UIGraphicsGetCurrentContext()];

    // Fetch the image
    UIImage *renderedImage = UIGraphicsGetImageFromCurrentImageContext();

    // Cleanup
    UIGraphicsEndImageContext();

    return renderedImage;
}

用法:

UIImage *image = [UIImage renderImageFromView:view withRect:view.bounds transparentInsets:UIEdgeInsetsZero];

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM