Uıımage üzerinde yuvarlatılmış köşeler

Ben Yuvarlak köşeleri kullanarak iPhone görüntüleri çizmek için çalışıyorum, A La kişiler uygulamasında iletişim görüntüleri. Genellikle çalışan kodum var, ancak bazen EXEC_BAD_ACCESS - KERN_INVALID_ADDRESS ile Uıımage çizim rutinlerinin içinde çöküyor . Bunun kırpma sorusu ile ilgili olabileceğini düşündüm. birkaç hafta önce sordum, ancak kırpma yolunu doğru bir şekilde kurduğuma inanıyorum.

işte kullandığım kod-ne zaman çökmez, sonuç iyi görünüyor ve benzer bir görünüm elde etmek isteyen herkes kodu ödünç almakta özgürdür.

- (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;
}

ve burada kilitlenme günlüğü. Bu çökmelerden birini aldığımda aynı görünüyor

Exception Type:  EXC_BAD_ACCESS (SIGSEGV)
Exception Codes: KERN_INVALID_ADDRESS at 0x6e2e6181
Crashed Thread:  0

Thread 0 Crashed:
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)
57
tarihinde sordu Community 2008-10-15 20:32:50
kaynak

11 ответов

burada iPhone 3.0 ve üstü kullanılabilir daha kolay bir yöntemdir. Nesne tabanlı her Görünüm ile ilişkili bir tabaka vardır. Her katman bir köşe yarıçapı seti olabilir, bu size sadece ne istediğinizi verecektir:

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]];
163
cevap MagicSeth 2009-08-20 21:33:08
kaynak

burada devam edeceğim ve aslında başlıktaki soruyu cevaplayacağım.

bu kategoriyi deneyin.

Uıımage+eklemeler.h

#import <UIKit/UIKit.h>

@interface UIImage (additions)
-(UIImage*)makeRoundCornersWithRadius:(const CGFloat)RADIUS;
@end

Uıımage+eklemeler.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
25
cevap Jonny 2013-09-03 10:56:36
kaynak

appİconİmage bir Uıımageview ise, o zaman:

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];

ve ayrıca hatırlıyorum:

#import <QuartzCore/QuartzCore.h>
21
cevap cuasijoe 2009-09-23 00:14:52
kaynak

kazanıza dair herhangi bir fikir sunamıyorum, ancak köşeleri yuvarlamak için başka bir seçenek sunacağımı düşündüm. Üzerinde çalıştığım bir uygulamada ortaya çıkan benzer bir problemim vardı. Herhangi bir kod yazmak yerine, köşeleri maskeleyen başka bir görüntüyü bindiriyorum.

4
cevap Lounges 2008-10-15 21:28:41
kaynak

yönteminizi (borderedİmageWithRect) bir arka plan iş parçacığında Çağırıyorsanız, UİGraphics-functions iş parçacığı güvenli olmadığından çökmeler oluşabilir. Böyle bir durumda, kullanarak bir bağlam oluşturmanız gerekir CGBİTMAPCONTEXTCREATE() - SDK "Yansıma" örnek koduna bakın.

4
cevap fjoachim 2009-01-17 04:38:00
kaynak

en kolay yolu bir engelli [embed etmektir!] yuvarlak-rect [özel değil! görünümünüzde] düğmesi (hatta arayüz Oluşturucu hepsini yapabilirsiniz)ve onunla görüntü ilişkilendirmek . Görüntü Ayarı mesajı uıbutton için farklıdır (Uıımageview ile karşılaştırıldığında), ancak genel kludge bir cazibe gibi çalışır. Setımage kullanın: forState: ortalanmış bir simge veya setbackgroundımage istiyorsanız: forState: köşeleri kesilmiş (kişiler gibi) ile tüm görüntüyü istiyorsanız. Tabii ki bu bir sürü görüntülemek istiyorsanız drawrect'inizdeki görüntüler bu doğru yaklaşım değildir, ancak daha büyük olasılıkla gömülü bir görünüm tam olarak ihtiyacınız olan şeydir...

3
cevap Max Motovilov 2008-12-17 03:47:16
kaynak

tekrar ediyorum fjoachim'in cevabı : ayrı bir iş parçacığı üzerinde çalışırken çizmeye çalışırken dikkatli olun veya EXC_BAD_ACCESS hatalarını alabilirsiniz.

geçici çözümüm şöyle bir şey yaptı:

UIImage *originalImage = [UIImage imageNamed:@"OriginalImage.png"] 
[self performSelectorOnMainThread:@selector(displayImageWithRoundedCorners:) withObject:originalImage waitUntilDone:YES];

(benim durumumda UI boyutunu yeniden boyutlandırıyordum / ölçeklendiriyordum).)

2
cevap PCheese 2017-05-23 14:45:49
kaynak

aslında bu konuda New York'ta iPhone Tech Talk Apple'dan biriyle konuşma şansım oldu. Bir şey düzgün çalışmıyor ve ne olduğundan emin değiliz. Bunun yerine, UIGraphicsBeginImageContext çağırırken oluşturulan grafik bağlamını korumam gerektiğini düşündü. Bu, genel kurallar ve adlandırma şemaları ile ilgili genel kuralları ihlal ediyor gibi görünüyor, ancak bu adam sorunu daha önce gördüğünden oldukça emindi.

bellek ise belki de başka bir iş parçacığı tarafından karalanmış oldu, bu kesinlikle neden sadece bazen sorunu gördüğümü açıklayacaktı.

kodu tekrar gözden geçirmek ve düzeltmeyi test etmek için zamanım olmadı, ancak Pcheese'nin yorumu, bilgiyi burada yayınlamadığımı fark etmemi sağladı.

...bunu yanlış yazmadığım sürece ve UIGraphicsBeginImageContext CGBitmapContextCreate olmalıydı ...

2
cevap Jablair 2009-02-04 13:10:58
kaynak

sadece bir süre çökerse, çarpışma vakalarının ortak noktası olduğunu anlayın. DstRect her seferinde aynı mı? Görüntüler hiç farklı bir boyut var mı?

ayrıca, CGPathRelease(borderPath) ye ihtiyacınız var , ancak bu sızıntıyı sorununuza neden olduğundan şüpheliyim.

1
cevap benzado 2008-10-15 23:07:13
kaynak
UIImage *originalImage = [UIImage imageNamed:@"OriginalImage.png"] 
[self performSelectorOnMainThread:@selector(displayImageWithRoundedCorners:) withObject:originalImage waitUntilDone:YES];
0
cevap user3536010 2015-02-04 12:24:00
kaynak

xıb veya storyboard (görüntü genişliği ve yüksekliği 41x41) görüntüyü ayarlayın.

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;
    }
-1
cevap Chris Emerson 2016-10-14 15:25:14
kaynak