Создайте новый UIImage, добавив тень к существующему UIImage - PullRequest
10 голосов
/ 30 мая 2010

Я посмотрел на этот вопрос: UIImage Shadow Trouble

Но принятый ответ не работал для меня.

То, что я пытаюсь сделать, это взять UIImage и добавить к нему тень, а затем вернуть совершенно новый UIImage, тень и все.

Вот что я пытаюсь:

- (UIImage*)imageWithShadow {

    CGColorSpaceRef colourSpace = CGColorSpaceCreateDeviceRGB();
    CGContextRef shadowContext = CGBitmapContextCreate(NULL, self.size.width, self.size.height + 1, CGImageGetBitsPerComponent(self.CGImage), 0, 
                                                 colourSpace, kCGImageAlphaPremultipliedLast);
    CGColorSpaceRelease(colourSpace);

    CGContextSetShadow(shadowContext, CGSizeMake(0, -1), 1);
    CGContextDrawImage(shadowContext, CGRectMake(0, 0, self.size.width, self.size.height), self.CGImage);

    CGImageRef shadowedCGImage = CGBitmapContextCreateImage(shadowContext);
    CGContextRelease(shadowContext);

    UIImage * shadowedImage = [UIImage imageWithCGImage:shadowedCGImage];
    CGImageRelease(shadowedCGImage);

    return shadowedImage;
}

В результате я получаю точно такое же изображение, как и раньше, используя этот метод.

Я делаю это правильно, или я что-то упускаю из виду?

Ответы [ 7 ]

16 голосов
/ 30 мая 2010

Есть несколько проблем с вашим кодом:

  • Целевое изображение слишком маленькое. Убедитесь, что есть достаточно места, чтобы нарисовать тень.
  • Попробуйте использовать CGContextSetShadowWithColor для определения как тени, так и ее цвета.
  • Не забывайте, что система координат перевернута, поэтому начало координат слева внизу, а не вверху слева.

Исправив эти проблемы, тень должна быть нарисована.

- (UIImage*)imageWithShadow {
    CGColorSpaceRef colourSpace = CGColorSpaceCreateDeviceRGB();
    CGContextRef shadowContext = CGBitmapContextCreate(NULL, self.size.width + 10, self.size.height + 10, CGImageGetBitsPerComponent(self.CGImage), 0, 
                                             colourSpace, kCGImageAlphaPremultipliedLast);
    CGColorSpaceRelease(colourSpace);

    CGContextSetShadowWithColor(shadowContext, CGSizeMake(5, -5), 5, [UIColor blackColor].CGColor);
    CGContextDrawImage(shadowContext, CGRectMake(0, 10, self.size.width, self.size.height), self.CGImage);

    CGImageRef shadowedCGImage = CGBitmapContextCreateImage(shadowContext);
    CGContextRelease(shadowContext);

    UIImage * shadowedImage = [UIImage imageWithCGImage:shadowedCGImage];
    CGImageRelease(shadowedCGImage);

    return shadowedImage;
}
7 голосов
/ 13 октября 2014

версия iOS8 / Swift (сделана как расширение UIImage):

extension UIImage {

    func addShadow(blurSize: CGFloat = 6.0) -> UIImage {

        let shadowColor = UIColor(white:0.0, alpha:0.8).cgColor

        let context = CGContext(data: nil,
                                width: Int(self.size.width + blurSize),
                                height: Int(self.size.height + blurSize),
                                bitsPerComponent: self.cgImage!.bitsPerComponent,
                                bytesPerRow: 0,
                                space: CGColorSpaceCreateDeviceRGB(),
                                bitmapInfo: CGImageAlphaInfo.premultipliedLast.rawValue)!

        context.setShadow(offset: CGSize(width: blurSize/2,height: -blurSize/2),
                          blur: blurSize,
                          color: shadowColor)
        context.draw(self.cgImage!,
                     in: CGRect(x: 0, y: blurSize, width: self.size.width, height: self.size.height),
                     byTiling:false)

        return UIImage(cgImage: context.makeImage()!)
    }
}

(преобразовано из ответов Лорана Этьембла и capikaw)

РЕДАКТИРОВАТЬ 2016/10/31: преобразовано в Swift 3 и удалены все ненужные вещи

Использование:

let sourceImage: UIImage(named: "some image")
let shadowImage = sourceImage.addShadow()
5 голосов
/ 28 июля 2011

Мне был нужен метод, который бы принимал UIImage в качестве параметра и возвращал немного больший UIImage с тенями. Сообщения здесь были очень полезны для меня, так что вот мой метод. Возвращенное изображение имеет центрированную тень размером 5 пикселей на каждой стороне.

+(UIImage*)imageWithShadowForImage:(UIImage *)initialImage {

CGColorSpaceRef colourSpace = CGColorSpaceCreateDeviceRGB();
CGContextRef shadowContext = CGBitmapContextCreate(NULL, initialImage.size.width + 10, initialImage.size.height + 10, CGImageGetBitsPerComponent(initialImage.CGImage), 0, colourSpace, kCGImageAlphaPremultipliedLast);
CGColorSpaceRelease(colourSpace);

CGContextSetShadowWithColor(shadowContext, CGSizeMake(0,0), 5, [UIColor blackColor].CGColor);
CGContextDrawImage(shadowContext, CGRectMake(5, 5, initialImage.size.width, initialImage.size.height), initialImage.CGImage);

CGImageRef shadowedCGImage = CGBitmapContextCreateImage(shadowContext);
CGContextRelease(shadowContext);

UIImage * shadowedImage = [UIImage imageWithCGImage:shadowedCGImage];
CGImageRelease(shadowedCGImage);

return shadowedImage;
}
4 голосов
/ 09 января 2013

Мне нужна была большая тень для моих UIImages. Вот мой вариант ответа, который позволяет настроить размер тени без смещения.

    - (UIImage*)imageWithShadow:(UIImage*)originalImage BlurSize:(float)blurSize {

    CGColorSpaceRef colourSpace = CGColorSpaceCreateDeviceRGB();
    CGContextRef shadowContext = CGBitmapContextCreate(NULL, originalImage.size.width + (blurSize*2), originalImage.size.height + (blurSize*2), CGImageGetBitsPerComponent(originalImage.CGImage), 0, colourSpace, kCGImageAlphaPremultipliedLast);
    CGColorSpaceRelease(colourSpace);

    CGContextSetShadowWithColor(shadowContext, CGSizeMake(0, 0), blurSize, [UIColor blackColor].CGColor);
    CGContextDrawImage(shadowContext, CGRectMake(blurSize, blurSize, originalImage.size.width, originalImage.size.height), originalImage.CGImage);

    CGImageRef shadowedCGImage = CGBitmapContextCreateImage(shadowContext);
    CGContextRelease(shadowContext);

    UIImage * shadowedImage = [UIImage imageWithCGImage:shadowedCGImage];
    CGImageRelease(shadowedCGImage);

    return shadowedImage;
}

Используйте это как:

UIImage *shadowedImage = [self imageWithShadow:myImage BlurSize:30.0f];
2 голосов
/ 15 апреля 2017

Мой метод, который рисует тень на изображении.Он имеет пользовательские параметры тени и отображает изображение в правильном размере и масштабе экрана.Должно быть реализовано в расширении UIImage.(Свифт 3).

func addingShadow(blur: CGFloat = 1, shadowColor: UIColor = UIColor(white: 0, alpha: 1), offset: CGSize = CGSize(width: 1, height: 1) ) -> UIImage {

    UIGraphicsBeginImageContextWithOptions(CGSize(width: size.width + 2 * blur, height: size.height + 2 * blur), false, 0)
    let context = UIGraphicsGetCurrentContext()!

    context.setShadow(offset: offset, blur: blur, color: shadowColor.cgColor)
    draw(in: CGRect(x: blur - offset.width / 2, y: blur - offset.height / 2, width: size.width, height: size.height))
    let image = UIGraphicsGetImageFromCurrentImageContext()!

    UIGraphicsEndImageContext()

    return image
}
0 голосов
/ 04 апреля 2016

GK100 ответ в Swift 2 / iOS9

func addShadow(blurSize: CGFloat = 6.0) -> UIImage {

    let data : UnsafeMutablePointer<Void> = nil
    let colorSpace:CGColorSpace = CGColorSpaceCreateDeviceRGB()!
    let bitmapInfo : CGBitmapInfo = CGBitmapInfo(rawValue: CGImageAlphaInfo.PremultipliedLast.rawValue)

    let myColorValues:[CGFloat] = [0.0, 0.0, 0.0, 0.8]
    let myColor = CGColorCreate(colorSpace, myColorValues)

    let shadowContext : CGContextRef = CGBitmapContextCreate(data, Int(self.size.width + blurSize), Int(self.size.height + blurSize), CGImageGetBitsPerComponent(self.CGImage), 0, colorSpace, bitmapInfo.rawValue)!

    CGContextSetShadowWithColor(shadowContext, CGSize(width: blurSize/2,height: -blurSize/2),  blurSize, myColor)
    CGContextDrawImage(shadowContext, CGRect(x: 0, y: blurSize, width: self.size.width, height: self.size.height), self.CGImage)

    let shadowedCGImage : CGImageRef = CGBitmapContextCreateImage(shadowContext)!
    let shadowedImage : UIImage = UIImage(CGImage: shadowedCGImage)

    return shadowedImage
}
0 голосов
/ 05 февраля 2013

Чтобы сделать изображение CGImage, как в этом случае, попробуйте

self.shadowImage.CGImage
...