1

I need to add a drop shadow on my image, not the image view. Is there anyway to do that? I know I can add shadow to imageView like -

imageView.layer.masksToBounds true
imageView.layer.shadowColor = UIColor.gray.cgColor
imageView.layer.shadowOffset = CGSizeMake(0, 1)
imageView.layer.shadowOpacity = 1
imageView.layer.shadowRadius = 1.0

but I need to add the shadow to the image, not imageView. Does anyone have any clue?

Natasha
  • 6,651
  • 3
  • 36
  • 58
  • 3
    Something like [this](https://stackoverflow.com/questions/2936443/create-new-uiimage-by-adding-shadow-to-existing-uiimage)? – MadProgrammer Sep 10 '21 at 01:16
  • Interesting @MadPogrammer. Wish there was a way to say your comment *is not* helpful. You linked to a question from 2010 - 11 years ago - with 8 answers, the accepted one is also from 2010 and uses Obj-C. Really not helpful on your part. –  Sep 10 '21 at 03:49
  • Sounds like there could be different solutions than what you’re asking for. Could you add an example of the image you have and how you want it to look like? – Renzo Tissoni Sep 10 '21 at 04:31
  • *"drop shadow on my image, not the image view"* -- you need to clarify what you're asking. Do you mean you have a `UIImage`, say, `200x150` pixels, and you want to generate a new `UIImage` with a thin drop shadow, so the resulting image would be (approx) `201x151` pixels? – DonMag Sep 10 '21 at 14:08
  • 1
    @MadProgrammer is absolutely right to offer you this question. You can find [this answer](https://stackoverflow.com/a/63494031/3585796), which is from 2020 and has modern swift syntax. Just in case you encounter an answer that is only available in ObjC in the future, I recommend you learn the skill of transforming code from ObjC to Swift. It is not something difficult, and the answers don't lose their relevance because all UIKit is still written in ObjC and in Swift we only use a wrapper over it. – Phil Dukhov Sep 10 '21 at 15:39
  • @dfd Funny, because I scrolled down and took two of the Swift versions and tried them out in playgrounds and was suitably impressed that I incorporated one of them into my personal library for future use – MadProgrammer Sep 10 '21 at 21:58
  • @dfd Of course, rather then criticising people for offering possible points of learning for other people, you could, maybe, present your own offerings, if you have better ones, I'd certainly be interested. My point of positing the link was to demonstrate that the OP might need to consider making some in roads on their own behalf to research the problem first - "I looked at several solutions, written in ObjC and couldn't make heads or tails of them", would have at least lead me to point out the number of Swift variants in the linked question – MadProgrammer Sep 10 '21 at 22:15
  • 1
    Possible duplicate of [Create new UIImage by adding shadow to existing UIImage](https://stackoverflow.com/questions/2936443/create-new-uiimage-by-adding-shadow-to-existing-uiimage) – pkamb Sep 28 '21 at 06:42

2 Answers2

0

I think you can use CIFilter in Core Image. CIFilter is an image processor that produces an image by manipulating one or more input images or by generating new image data.

You can check various references here.

I think you can CIHighlightShadowAdjust CIHighlightShadowAdjust is the properties you use to configure a highlight-shadow adjust filter.

Hailey
  • 302
  • 1
  • 7
0

Just for @dfd.

So, I went and had a look at Create new UIImage by adding shadow to existing UIImage. After scrolling down a bit, I started to find several Swift based solutions. Intrigued, I threw them into a Playground to see what they could do.

I settled on this solution...

import UIKit

extension UIImage {
    /// Returns a new image with the specified shadow properties.
    /// This will increase the size of the image to fit the shadow and the original image.
    func withShadow(blur: CGFloat = 6, offset: CGSize = .zero, color: UIColor = UIColor(white: 0, alpha: 0.8)) -> UIImage {

        let shadowRect = CGRect(
            x: offset.width - blur,
            y: offset.height - blur,
            width: size.width + blur * 2,
            height: size.height + blur * 2
        )
        
        UIGraphicsBeginImageContextWithOptions(
            CGSize(
                width: max(shadowRect.maxX, size.width) - min(shadowRect.minX, 0),
                height: max(shadowRect.maxY, size.height) - min(shadowRect.minY, 0)
            ),
            false, 0
        )
        
        let context = UIGraphicsGetCurrentContext()!

        context.setShadow(
            offset: offset,
            blur: blur,
            color: color.cgColor
        )
        
        draw(
            in: CGRect(
                x: max(0, -shadowRect.origin.x),
                y: max(0, -shadowRect.origin.y),
                width: size.width,
                height: size.height
            )
        )
        let image = UIGraphicsGetImageFromCurrentImageContext()!
        
        UIGraphicsEndImageContext()
        return image
    }
}

let sourceImage = UIImage(named: "LogoSmall.png")!

let shadowed = sourceImage.withShadow(blur: 6, color: .red)

Outline

But wait, that's not a drop shadow, it's an outline!

Apparently we need to hand hold everybody now days...

Changing the parameters to ...

let shadowed = sourceImage.withShadow(blur: 6, offset: CGSize(width: 5, height: 5), color: .red)

Dropshow

Produces a drop shadow. I like the solution because it doesn't make assumptions and provides a suitable number of parameters to change the output as desired.

I liked the solution so much, I copied the extension into my personal library, never know when it might come in handy.

Remember, in order to produce this style of image, the original image needs to be transparent.

A little bit like...

A little logo

Remember, iOS has been around a LONG time, ObjC has been around even longer. You're likely to come across many solutions which are only presented in ObjC, which means, it's still important to have the skill/ability to at least read the code. If we're lucky, other members of the community will produce suitable Swift variants, but this isn't always possible.

I'm sure I don't need to go to the extent of writing a full tutorial on how to include images in Playground, there are plenty of examples about that

MadProgrammer
  • 343,457
  • 22
  • 230
  • 366