davidbyttow / govips

A lightning fast image processing and resizing library for Go
MIT License
1.28k stars 199 forks source link

Drop shadow under image #315

Closed roffe closed 2 years ago

roffe commented 2 years ago

Hope it comes to use for someone, took me a while to figure out how to do after seeing example here: https://github.com/libvips/libvips/discussions/2385

func Shadow(img *vips.ImageRef, sigma, offset int) error {
    if !img.HasAlpha() {
        img.AddAlpha()
    }

    shadowAlpha, err := img.Copy()
    if err != nil {
        return err
    }
    defer shadowAlpha.Close()

    if err := shadowAlpha.ExtractBand(3, 1); err != nil {
        return err
    }

    err = shadowAlpha.Embed(
        offset,
        offset,
        shadowAlpha.Width()+offset+sigma,
        shadowAlpha.Height()+offset+sigma,
        vips.ExtendBackground,
    )
    if err != nil {
        return err
    }
    if err := shadowAlpha.GaussianBlur(float64(sigma / 2)); err != nil {
        return err
    }

    shadow, err := vips.Black(shadowAlpha.Width(), shadowAlpha.Height())
    if err != nil {
        return err
    }
    defer shadow.Close()

    if err := shadow.ToColorSpace(vips.InterpretationSRGB); err != nil {
        return err
    }

    err = shadow.DrawRect(vips.ColorRGBA{R: 0x2e, G: 0x2e, B: 0x30}, 0, 0, shadowAlpha.Width(), shadowAlpha.Height(), true)
    if err != nil {
        return err
    }

    if err := shadow.BandJoin(shadowAlpha); err != nil {
        return err
    }

    err = img.Embed(0, 0,
        shadow.Width(),
        shadow.Height(),
        vips.ExtendBackground,
    )
    if err != nil {
        return err
    }

    return img.Composite(shadow, vips.BlendModeDestOver, offset, offset)
}

sigma 27 and offset 9 used on the image bellow

12