2010-05-29 17 views
9

He echado un vistazo a esta pregunta: UIImage Shadow TroubleCrear nueva UIImage añadiendo a la sombra UIImage existente

Pero la respuesta aceptada no funcionó para mí.

Lo que estoy tratando de hacer es tomar un UIImage y agregarle una sombra, luego devolver un UIImage completamente nuevo, sombra y todo.

Esto es lo que trato:

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

El resultado es que me sale exactamente la misma imagen que antes de poner a través de este método.

Estoy haciendo esto de la manera correcta, o hay algo obvio que me falta?

Respuesta

14

Hay varios problemas con su código:

  • imagen El objetivo demasiado pequeño. Asegúrate de que haya suficiente lugar para dibujar la sombra.
  • Considere usar CGContextSetShadowWithColor para definir tanto la sombra como su color.
  • No olvide que el sistema de coordenadas está volteado, por lo que el origen es inferior izquierdo, no superior izquierdo.

Al solucionar estos problemas, se debe dibujar la sombra.

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

¡Perfecto! De hecho, estaba agregando 1 a la altura para dibujar la sombra, pero el resto (configurar la sombra, el sistema de coordenadas volteado) estaba en el blanco. –

+0

¿Dónde se implementaría este código y cómo lo llamarías para agregar una sombra a una imagen? –

+0

El método supone que la clase puede proporcionar una CGImage y sus dimensiones. Puede modificar el método para tomar parámetros (CGImage y CGSize) en su lugar. –

5

Necesitaba un método que aceptara un UIImage como parámetro y devolviera un UIImage ligeramente más grande con sombras. Las publicaciones aquí me han sido muy útiles, así que este es mi método. La imagen devuelta tiene una sombra centrada de 5 píxeles en cada lado.

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

Necesitaba una sombra más grande para mis UIImages. Aquí está mi variante de la respuesta que permite un tamaño de sombra personalizado sin compensación.

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

usarlo como:

UIImage *shadowedImage = [self imageWithShadow:myImage BlurSize:30.0f]; 
0

para hacer una imagen de un CGImage como en este caso, intente

self.shadowImage.CGImage 
4

iOS8 versión/Swift (hecho como una extensión de 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()!) 
    } 
} 

(con verted de & respuestas capikaw de Laurent Etiemble)

EDITAR 31/10/2016: convertido a Swift 3, y se retira toda la materia innecesaria

Uso:

let sourceImage: UIImage(named: "some image") 
let shadowImage = sourceImage.addShadow() 
+0

Actualícelo para Swift 2.0 – itsji10dra

+0

respuesta genial +1 para usted – Vats

0

respuesta de GK100 en 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 
} 
1

Mi método que dibuja una sombra en una imagen. Tiene parámetros de sombra personalizados y representa la imagen en el tamaño correcto y la escala de pantalla. Debería implementarse en la extensión UIImage. (Swift 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 
}