it-swarm.com.de

UIImage abgerundete Ecken

Ich versuche auf einem UIImage abgerundete Ecken zu bekommen. Was ich bisher gelesen habe, ist der einfachste Weg, Maskenbilder zu verwenden. Dafür habe ich Code von TheElements iPhone Example und einen Code zum Ändern der Bildgröße verwendet, den ich gefunden habe. Mein Problem ist, dass resizedImage immer gleich Null ist und ich den Fehler nicht finde ...

- (UIImage *)imageByScalingProportionallyToSize:(CGSize)targetSize
{
    CGSize imageSize = [self size];
    float width = imageSize.width;
    float height = imageSize.height;

    // scaleFactor will be the fraction that we'll
    // use to adjust the size. For example, if we shrink
    // an image by half, scaleFactor will be 0.5. the
    // scaledWidth and scaledHeight will be the original,
    // multiplied by the scaleFactor.
    //
    // IMPORTANT: the "targetHeight" is the size of the space
    // we're drawing into. The "scaledHeight" is the height that
    // the image actually is drawn at, once we take into
    // account the ideal of maintaining proportions

    float scaleFactor = 0.0; 
    float scaledWidth = targetSize.width;
    float scaledHeight = targetSize.height;

    CGPoint thumbnailPoint = CGPointMake(0,0);

    // since not all images are square, we want to scale
    // proportionately. To do this, we find the longest
    // Edge and use that as a guide.

    if ( CGSizeEqualToSize(imageSize, targetSize) == NO )
    { 
        // use the longeset Edge as a guide. if the
        // image is wider than tall, we'll figure out
        // the scale factor by dividing it by the
        // intended width. Otherwise, we'll use the
        // height.

        float widthFactor = targetSize.width / width;
        float heightFactor = targetSize.height / height;

        if ( widthFactor < heightFactor )
            scaleFactor = widthFactor;
        else
            scaleFactor = heightFactor;

        // ex: 500 * 0.5 = 250 (newWidth)

        scaledWidth = width * scaleFactor;
        scaledHeight = height * scaleFactor;

        // center the thumbnail in the frame. if
        // wider than tall, we need to adjust the
        // vertical drawing point (y axis)

        if ( widthFactor < heightFactor )
            thumbnailPoint.y = (targetSize.height - scaledHeight) * 0.5;

        else if ( widthFactor > heightFactor )
            thumbnailPoint.x = (targetSize.width - scaledWidth) * 0.5;
    }


    CGContextRef mainViewContentContext;
    CGColorSpaceRef colorSpace;

    colorSpace = CGColorSpaceCreateDeviceRGB();

    // create a bitmap graphics context the size of the image
    mainViewContentContext = CGBitmapContextCreate (NULL, targetSize.width, targetSize.height, 8, 0, colorSpace, kCGImageAlphaPremultipliedLast);

    // free the rgb colorspace
    CGColorSpaceRelease(colorSpace);    

    if (mainViewContentContext==NULL)
        return NULL;

    //CGContextSetFillColorWithColor(mainViewContentContext, [[UIColor whiteColor] CGColor]);
    //CGContextFillRect(mainViewContentContext, CGRectMake(0, 0, targetSize.width, targetSize.height));

    CGContextDrawImage(mainViewContentContext, CGRectMake(thumbnailPoint.x, thumbnailPoint.y, scaledWidth, scaledHeight), self.CGImage);

    // Create CGImageRef of the main view bitmap content, and then
    // release that bitmap context
    CGImageRef mainViewContentBitmapContext = CGBitmapContextCreateImage(mainViewContentContext);
    CGContextRelease(mainViewContentContext);

    CGImageRef maskImage = [[UIImage imageNamed:@"Mask.png"] CGImage];

    CGImageRef resizedImage = CGImageCreateWithMask(mainViewContentBitmapContext, maskImage);
    CGImageRelease(mainViewContentBitmapContext);

    // convert the finished resized image to a UIImage 
    UIImage *theImage = [UIImage imageWithCGImage:resizedImage];

    // image is retained by the property setting above, so we can 
    // release the original
    CGImageRelease(resizedImage);

    // return the image
    return theImage;
}
57
catlan

Das Problem war die Verwendung von CGImageCreateWithMask, die ein vollständig schwarzes Bild zurückgab. Die Lösung, die ich gefunden habe, war stattdessen CGContextClipToMask zu verwenden:

CGContextRef mainViewContentContext;
CGColorSpaceRef colorSpace;

colorSpace = CGColorSpaceCreateDeviceRGB();

// create a bitmap graphics context the size of the image
mainViewContentContext = CGBitmapContextCreate (NULL, targetSize.width, targetSize.height, 8, 0, colorSpace, kCGImageAlphaPremultipliedLast);

// free the rgb colorspace
CGColorSpaceRelease(colorSpace);    

if (mainViewContentContext==NULL)
    return NULL;

CGImageRef maskImage = [[UIImage imageNamed:@"mask.png"] CGImage];
CGContextClipToMask(mainViewContentContext, CGRectMake(0, 0, targetSize.width, targetSize.height), maskImage);
CGContextDrawImage(mainViewContentContext, CGRectMake(thumbnailPoint.x, thumbnailPoint.y, scaledWidth, scaledHeight), self.CGImage);


// Create CGImageRef of the main view bitmap content, and then
// release that bitmap context
CGImageRef mainViewContentBitmapContext = CGBitmapContextCreateImage(mainViewContentContext);
CGContextRelease(mainViewContentContext);

// convert the finished resized image to a UIImage 
UIImage *theImage = [UIImage imageWithCGImage:mainViewContentBitmapContext];
// image is retained by the property setting above, so we can 
// release the original
CGImageRelease(mainViewContentBitmapContext);

// return the image
return theImage;
14
catlan

Wenn Sie ein UIImageView verwenden, um das Bild anzuzeigen, können Sie einfach Folgendes tun:

imageView.layer.cornerRadius = 5.0;
imageView.layer.masksToBounds = YES;

Und eine Grenze hinzufügen:

imageView.layer.borderColor = [UIColor lightGrayColor].CGColor;
imageView.layer.borderWidth = 1.0;

Ich glaube, dass Sie <QuartzCore/QuartzCore.h> importieren und dagegen verlinken müssen, damit der obige Code funktioniert.

203
jessecurry

Wie wäre es mit diesen Zeilen?.

// Get your image somehow
UIImage *image = [UIImage imageNamed:@"image.jpg"];

// Begin a new image that will be the new image with the rounded corners 
// (here with the size of an UIImageView)
UIGraphicsBeginImageContextWithOptions(imageView.bounds.size, NO, 1.0);

// Add a clip before drawing anything, in the shape of an rounded rect
[[UIBezierPath bezierPathWithRoundedRect:imageView.bounds 
                            cornerRadius:10.0] addClip];
// Draw your image
[image drawInRect:imageView.bounds];

// Get the image, here setting the UIImageView image
imageView.image = UIGraphicsGetImageFromCurrentImageContext();

// Lets forget about that we were drawing
UIGraphicsEndImageContext();
84
epatel

Ich habe in Swift eine UIImage- -Erweiterung erstellt, basierend auf @ epatels großartiger Antwort:

extension UIImage{
    var roundedImage: UIImage {
        let rect = CGRect(Origin:CGPoint(x: 0, y: 0), size: self.size)
        UIGraphicsBeginImageContextWithOptions(self.size, false, 1)
        UIBezierPath(
            roundedRect: rect,
            cornerRadius: self.size.height
            ).addClip()
        self.drawInRect(rect)
        return UIGraphicsGetImageFromCurrentImageContext()
    }
}

In einem Storyboard getestet:

 storyboard

27
Besi

Sie machen eigentlich nichts anderes als dort zu skalieren. Sie müssen die Ecken des Bildes "maskieren", indem Sie es mit einem CGPath ausschneiden. Zum Beispiel - 

 - (void)drawRect:(CGRect)rect {
    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextBeginTransparencyLayerWithRect(context, self.frame, NULL);
    CGContextSetRGBFillColor(context, 1.0, 1.0, 1.0, 1.0);  
    CGFloat roundRadius = (radius) ? radius : 12.0;
    CGFloat minx = CGRectGetMinX(self.frame), midx = CGRectGetMidX(self.frame), maxx = CGRectGetMaxX(self.frame);
    CGFloat miny = CGRectGetMinY(self.frame), midy = CGRectGetMidY(self.frame), maxy = CGRectGetMaxY(self.frame);

    // draw the arcs, handle paths
    CGContextMoveToPoint(context, minx, midy);
    CGContextAddArcToPoint(context, minx, miny, midx, miny, roundRadius);
    CGContextAddArcToPoint(context, maxx, miny, maxx, midy, roundRadius);
    CGContextAddArcToPoint(context, maxx, maxy, midx, maxy, roundRadius);
    CGContextAddArcToPoint(context, minx, maxy, minx, midy, roundRadius);
    CGContextClosePath(context);
    CGContextDrawPath(context, kCGPathFill);
    CGContextEndTransparencyLayer(context);
}

Ich schlage vor, die Programmieranleitung für Quartz 2D oder andere Beispiele zu überprüfen.

5
wisequark
static void addRoundedRectToPath(CGContextRef context, CGRect rect, float ovalWidth, float ovalHeight)
{
  float fw, fh;
  if (ovalWidth == 0 || ovalHeight == 0) {
    CGContextAddRect(context, rect);
    return;
  }
  CGContextSaveGState(context);
  CGContextTranslateCTM (context, CGRectGetMinX(rect), CGRectGetMinY(rect));
  CGContextScaleCTM (context, ovalWidth, ovalHeight);
  fw = CGRectGetWidth (rect) / ovalWidth;
  fh = CGRectGetHeight (rect) / ovalHeight;
  CGContextMoveToPoint(context, fw, fh/2);
  CGContextAddArcToPoint(context, fw, fh, fw/2, fh, 1);
  CGContextAddArcToPoint(context, 0, fh, 0, fh/2, 1);
  CGContextAddArcToPoint(context, 0, 0, fw/2, 0, 1);
  CGContextAddArcToPoint(context, fw, 0, fw, fh/2, 1);
  CGContextClosePath(context);
  CGContextRestoreGState(context);
}

+ (UIImage *)imageWithRoundCorner:(UIImage*)img andCornerSize:(CGSize)size
{
    UIImage * newImage = nil;

    if( nil != img)
    {
       @autoreleasepool {
        int w = img.size.width;
        int h = img.size.height;

        CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
        CGContextRef context = CGBitmapContextCreate(NULL, w, h, 8, 4 * w, colorSpace, kCGImageAlphaPremultipliedFirst);

        CGContextBeginPath(context);
        CGRect rect = CGRectMake(0, 0, img.size.width, img.size.height);
        addRoundedRectToPath(context, rect, size.width, size.height);
        CGContextClosePath(context);
        CGContextClip(context);

        CGContextDrawImage(context, CGRectMake(0, 0, w, h), img.CGImage);

        CGImageRef imageMasked = CGBitmapContextCreateImage(context);
        CGContextRelease(context);
        CGColorSpaceRelease(colorSpace);
        [img release];

        newImage = [[UIImage imageWithCGImage:imageMasked] retain];
        CGImageRelease(imageMasked);

       }
    }

  return newImage;
}
4
Voda Ion

Hallo Jungs, versuche diesen Code,

+ (UIImage *)roundedRectImageFromImage:(UIImage *)image withRadious:(CGFloat)radious {

if(radious == 0.0f)
    return image;

if( image != nil) {

    CGFloat imageWidth = image.size.width;
    CGFloat imageHeight = image.size.height;

    CGRect rect = CGRectMake(0.0f, 0.0f, imageWidth, imageHeight);
    UIWindow *window = [[[UIApplication sharedApplication] windows] objectAtIndex:0];
    const CGFloat scale = window.screen.scale;
    UIGraphicsBeginImageContextWithOptions(rect.size, NO, scale);

    CGContextRef context = UIGraphicsGetCurrentContext();

    CGContextBeginPath(context);
    CGContextSaveGState(context);
    CGContextTranslateCTM (context, CGRectGetMinX(rect), CGRectGetMinY(rect));
    CGContextScaleCTM (context, radious, radious);

    CGFloat rectWidth = CGRectGetWidth (rect)/radious;
    CGFloat rectHeight = CGRectGetHeight (rect)/radious;

    CGContextMoveToPoint(context, rectWidth, rectHeight/2.0f);
    CGContextAddArcToPoint(context, rectWidth, rectHeight, rectWidth/2.0f, rectHeight, radious);
    CGContextAddArcToPoint(context, 0.0f, rectHeight, 0.0f, rectHeight/2.0f, radious);
    CGContextAddArcToPoint(context, 0.0f, 0.0f, rectWidth/2.0f, 0.0f, radious);
    CGContextAddArcToPoint(context, rectWidth, 0.0f, rectWidth, rectHeight/2.0f, radious);
    CGContextRestoreGState(context);
    CGContextClosePath(context);
    CGContextClip(context);

    [image drawInRect:CGRectMake(0.0f, 0.0f, imageWidth, imageHeight)];

    UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    return newImage;
}

return nil;
}

Prost !!!

2
Augustine P A

Erweiterung Besis ausgezeichnete Antwort mit korrekter Skala in Swift 4:

extension UIImage {

    public func rounded(radius: CGFloat) -> UIImage {
        let rect = CGRect(Origin: .zero, size: size)
        UIGraphicsBeginImageContextWithOptions(size, false, scale)
        UIBezierPath(roundedRect: rect, cornerRadius: radius).addClip()
        draw(in: rect)
        return UIGraphicsGetImageFromCurrentImageContext()!
    }

}
1
samwize

Den besten und einfachsten Weg herauszufinden, ist wie folgt (keine Antwort hat das getan):

UIImageView *imageView;

imageView.layer.cornerRadius = imageView.frame.size.width/2.0f;
imageView.layer.masksToBounds = TRUE;

Ziemlich einfach und richtig gemacht.

1
Idan

Es ist sehr einfach, ein abgerundetes Bild zu erstellen, wenn Sie die Bildgröße verwenden.

cell.messageImage.layer.cornerRadius = image.size.width / 2
cell.messageImage.layer.masksToBounds = true
1
bartosss

Der Grund, warum es mit dem Beschneiden gearbeitet hat, und nicht mit dem Maskieren, scheint der Farbraum zu sein. 

Apple-Dokumentation ist unten.

maske Eine Maske. Wenn es sich bei der Maske um ein Bild handelt, muss es sich im DeviceGray-Farbraum befinden, darf keine Alphakomponente enthalten und darf nicht selbst durch eine Bildmaske oder eine Maskierungsfarbe maskiert werden. Wenn die Maske nicht die gleiche Größe hat wie das durch den Bildparameter angegebene Bild, skaliert Quartz die Maske an das Bild.

1
sang

Ich hatte Mühe, die Ecken einer UIImage-Box in meinem Storyboard zu umrunden. Ich hatte ein IBOutlet für mein UIImage namens image. Nachdem ich hier ein paar Posts gelesen hatte, habe ich einfach 3 Zeilen hinzugefügt und das hat perfekt funktioniert. 

import UIKit

Dann in viewDidLoad:

image.layer.cornerRadius = 20.0

image.layer.masksToBounds = true

Dies ist für iOS 11.1 in Xcode 9.

0
Donsb

Siehe hier ... IMO, sofern Sie dies nicht unbedingt im Code tun müssen, legen Sie einfach ein Bild darüber.

Etwas in der Richtung von ...

- (void)drawRect:(CGRect)rect 
{
    // Drawing code
    [backgroundImage drawInRect:rect];
    [buttonOverlay drawInRect:rect];    
}
0
Lounges

Ich denke, das könnte sehr verwandt sein: In iOS 11 gibt es eine sehr elegante Art, jede einzelne Ecke einer (Bild-) Ansicht zu runden.

let imageView = UIImageView(image: UIImage(named: "myImage"))    
imageView.layer.maskedCorners = [.layerMinXMinYCorner, .layerMaxXMinYCorner]
imageView.layer.cornerRadius = 10.0
0
scrat84

Für das Erstellen eines runden Eckbilds können wir Quarzkern verwenden.

Erste Wie füge ich das QuartzCore-Framework hinzu?

Click  project -Targets
    ->project
       ->BuildPhase
           ->Link Binary with Libraries
             ->Then click + symbol finally select from list and add it

oder aber

Click  project -Targets
    ->Targets
      ->general
        ->Linked Frameworks and Libraries
          ->Then click + symbol finally select from list and add the QuartzCore framework

Jetzt importieren 

#import <QuartzCore/QuartzCore.h> 

in Ihrem ViewController

Dann in der viewDidLoad-Methode

self.yourImageView.layer.cornerRadius = 5.0;
self.yourImageView.layer.borderWidth = 1.0f;
self.yourImageView.layer.borderColor = [UIColor blackColor].CGColor;
self.yourImageView.layer.masksToBounds = YES;
0
user3182143