UIImage의 둥근 모서리
둥근 모서리를 사용하여 iPhone에서 이미지를 그리려고합니다. 연락처 앱의 연락처 이미지입니다. 일반적으로 작동하는 코드가 있지만 UIImage 그리기 루틴 내부에서 EXEC_BAD_ACCESS
- KERN_INVALID_ADDRESS
. 나는 이것이 내가 몇 주 전에 물어 본 자르기 질문 과 관련이 있다고 생각 했지만 내가 자르기 경로를 올바르게 설정하고 있다고 생각합니다.
여기에 제가 사용하고있는 코드가 있습니다. 충돌하지 않으면 결과는 괜찮아 보이고 비슷한 모양을 원하는 사람은 누구나 코드를 빌릴 수 있습니다.
- (UIImage *)borderedImageWithRect: (CGRect)dstRect radius:(CGFloat)radius {
UIImage *maskedImage = nil;
radius = MIN(radius, .5 * MIN(CGRectGetWidth(dstRect), CGRectGetHeight(dstRect)));
CGRect interiorRect = CGRectInset(dstRect, radius, radius);
UIGraphicsBeginImageContext(dstRect.size);
CGContextRef maskedContextRef = UIGraphicsGetCurrentContext();
CGContextSaveGState(maskedContextRef);
CGMutablePathRef borderPath = CGPathCreateMutable();
CGPathAddArc(borderPath, NULL, CGRectGetMinX(interiorRect), CGRectGetMinY(interiorRect), radius, PNDegreeToRadian(180), PNDegreeToRadian(270), NO);
CGPathAddArc(borderPath, NULL, CGRectGetMaxX(interiorRect), CGRectGetMinY(interiorRect), radius, PNDegreeToRadian(270.0), PNDegreeToRadian(360.0), NO);
CGPathAddArc(borderPath, NULL, CGRectGetMaxX(interiorRect), CGRectGetMaxY(interiorRect), radius, PNDegreeToRadian(0.0), PNDegreeToRadian(90.0), NO);
CGPathAddArc(borderPath, NULL, CGRectGetMinX(interiorRect), CGRectGetMaxY(interiorRect), radius, PNDegreeToRadian(90.0), PNDegreeToRadian(180.0), NO);
CGContextBeginPath(maskedContextRef);
CGContextAddPath(maskedContextRef, borderPath);
CGContextClosePath(maskedContextRef);
CGContextClip(maskedContextRef);
[self drawInRect: dstRect];
maskedImage = UIGraphicsGetImageFromCurrentImageContext();
CGContextRestoreGState(maskedContextRef);
UIGraphicsEndImageContext();
return maskedImage;
}
여기 충돌 로그가 있습니다. 이 충돌 중 하나가 발생할 때마다 동일하게 보입니다.
예외 유형 : EXC_BAD_ACCESS (SIGSEGV) 예외 코드 : 0x6e2e6181의 KERN_INVALID_ADDRESS 충돌 스레드 : 0 스레드 0 충돌 : 0 com.apple.CoreGraphics 0x30fe56d8 CGGStateGetRenderingIntent + 4 1 libRIP.A.dylib 0x33c4a7d8 ripc_RenderImage + 104 2 libRIP.A.dylib 0x33c51868 ripc_DrawImage + 3860 3 com.apple.CoreGraphics 0x30fecad4 CGContextDelegateDrawImage + 80 4 com.apple.CoreGraphics 0x30feca40 CGContextDrawImage + 368 5 UIKit 0x30a6a708-[UIImage drawInRect : blendMode : alpha :] + 1460 6 UIKit 0x30a66904-[UIImage drawInRect :] + 72 7 MyApp 0x0003f8a8-[UIImage (PNAdditions) borderedImageWithRect : radius :] (UIImage + PNAdditions.m : 187)
다음은 iPhone 3.0 이상에서 사용할 수있는 더 쉬운 방법입니다. 모든보기 기반 개체에는 연결된 레이어가 있습니다. 각 레이어는 모서리 반경을 설정할 수 있으며 원하는 것을 제공합니다.
UIImageView * roundedView = [[UIImageView alloc] initWithImage: [UIImage imageNamed:@"wood.jpg"]];
// Get the Layer of any view
CALayer * l = [roundedView layer];
[l setMasksToBounds:YES];
[l setCornerRadius:10.0];
// You can even add a border
[l setBorderWidth:4.0];
[l setBorderColor:[[UIColor blueColor] CGColor]];
여기로 가서 제목에있는 질문에 실제로 답하겠습니다.
이 카테고리를 시도하십시오.
UIImage + additions.h
#import <UIKit/UIKit.h>
@interface UIImage (additions)
-(UIImage*)makeRoundCornersWithRadius:(const CGFloat)RADIUS;
@end
UIImage + additions.m
#import "UIImage+additions.h"
@implementation UIImage (additions)
-(UIImage*)makeRoundCornersWithRadius:(const CGFloat)RADIUS {
UIImage *image = self;
// Begin a new image that will be the new image with the rounded corners
// (here with the size of an UIImageView)
UIGraphicsBeginImageContextWithOptions(image.size, NO, image.scale);
const CGRect RECT = CGRectMake(0, 0, image.size.width, image.size.height);
// Add a clip before drawing anything, in the shape of an rounded rect
[[UIBezierPath bezierPathWithRoundedRect:RECT cornerRadius:RADIUS] addClip];
// Draw your image
[image drawInRect:RECT];
// Get the image, here setting the UIImageView image
//imageView.image
UIImage* imageNew = UIGraphicsGetImageFromCurrentImageContext();
// Lets forget about that we were drawing
UIGraphicsEndImageContext();
return imageNew;
}
@end
appIconImage가 UIImageView 인 경우 :
appIconImage.image = [UIImage imageWithContentsOfFile:@"image.png"];
appIconImage.layer.masksToBounds = YES;
appIconImage.layer.cornerRadius = 10.0;
appIconImage.layer.borderWidth = 1.0;
appIconImage.layer.borderColor = [[UIColor grayColor] CGColor];
또한 다음 사항을 기억하십시오.
#import <QuartzCore/QuartzCore.h>
나는 당신의 충돌에 대한 통찰력을 제공 할 수 없지만 모서리를 둥글게하기위한 또 다른 옵션을 제공 할 것이라고 생각했습니다. 작업중인 응용 프로그램에서 비슷한 문제가 발생했습니다. 코드를 작성하는 대신 모서리를 가리는 다른 이미지를 오버레이하고 있습니다.
If you are calling your method (borderedImageWithRect) in a background thread, crashes might occur since UIGraphics-functions are not thread-safe. In such a case, you must create a context using CGBitmapContextCreate() - see the "Reflection" sample code from the SDK.
The easiest way is to embed a disabled[!] round-rect [not custom!] button in your view (can even do it all in the Interface Builder) and associate your image with it. The image-setting message is different for UIButton (compared to UIImageView), but the overall kludge works like a charm. Use setImage:forState: if you want a centered icon or setBackgroundImage:forState: if you want the whole image with corners cut (like Contacts). Of course if you want to display lots of these images in your drawRect this isn't the right approach, but more likely an embedded view is exactly what you needed anyway...
I would reiterate fjoachim's answer: be cautious when attempting to draw while running on a separate thread, or you may get EXC_BAD_ACCESS
errors.
My workaround went something like this:
UIImage *originalImage = [UIImage imageNamed:@"OriginalImage.png"]
[self performSelectorOnMainThread:@selector(displayImageWithRoundedCorners:) withObject:originalImage waitUntilDone:YES];
(In my case I was resizing / scaling UIImages.)
I actually had a chance to talk about this with somebody from Apple at the iPhone Tech Talk in New York. When we talked about it, he was pretty sure it wasn't a threading issued. Instead, he thought that I needed to retain the graphics context that was generated when calling UIGraphicsBeginImageContext
. This seems to violate the general rules dealing with retain rules and naming schemes, but this fellow was pretty sure he'd seen the issue previously.
If the memory was getting scribbled, perhaps by another thread, that would certainly explain why I was only seeing the issue occasionally.
I haven't had time to revisit the code and test out the fix, but PCheese's comment made me realize I hadn't posted the info here.
...unless I wrote that down wrong and UIGraphicsBeginImageContext
should've been CGBitmapContextCreate
...
If it only crashes some of the time, figure out what the crash cases have in common. Is dstRect the same every time? Are the images ever a different size?
Also, you need to CGPathRelease(borderPath)
, although I doubt that leak is causing your problem.
UIImage *originalImage = [UIImage imageNamed:@"OriginalImage.png"]
[self performSelectorOnMainThread:@selector(displayImageWithRoundedCorners:) withObject:originalImage waitUntilDone:YES];
In Swift 4.2 and Xcode 10.1
let imgView = UIImageView()
imgView.frame = CGRect(x: 200, y: 200, width: 200, height: 200)
imgView.image = UIImage(named: "yourimagename")
imgView.imgViewCorners()
//If you want complete round shape
//imgView.imgViewCorners(width: imgView.frame.width)//Pass ImageView width
view.addSubview(imgView)
extension UIImageView {
//If you want only round corners
func imgViewCorners() {
layer.cornerRadius = 10
layer.borderWidth = 1.0
layer.borderColor = UIColor.red.cgColor
layer.masksToBounds = true
}
//If you want complete round shape
func imgViewCorners(width:CGFloat) {
layer.cornerRadius = width/2
layer.borderWidth = 1.0
layer.borderColor = UIColor.red.cgColor
layer.masksToBounds = true
}
Set the Image in xib or storyboard (image width and height 41x41).
FirstViewController.h
@interface....
IBOutlet UIImageView *testImg;
@end
FirstViewController.m
-(void)viewDidLoad{
testImg.layer.backgroundColor=[[UIColor clearColor] CGColor];
testImg.layer.cornerRadius=20;
testImg.layer.masksToBounds = YES;
}
참고URL : https://stackoverflow.com/questions/205431/rounded-corners-on-uiimage
'Program Tip' 카테고리의 다른 글
스레드 세이프 싱글 톤 클래스 (0) | 2020.12.09 |
---|---|
PHP의 최대 실행 시간 늘리기 (0) | 2020.12.09 |
ORM 및 Embedded SQL없이 Java 웹 애플리케이션을 디자인하려면 어떻게해야합니까? (0) | 2020.12.09 |
스크롤 방향을 감지하는 방법 (0) | 2020.12.09 |
아직없는 경우 배열에 추가 (0) | 2020.12.09 |