Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to programmatically remove the background of an image making it transparent in ruby?

I have a bunch of images of products and I'd like to remove the background of each programmatically in ruby. Here are some example images I put up on imgur.

enter image description here

I'll put an example one here just so you can see but I didn't want to post a bunch of images. This is the simplest of all of them. It has just a white background but some of the products have more complex backgrounds. I know doing something like this on this image probably isn't going to work so I'd like to figure that out and fail gracefully by not actually removing the background and just notifying me somehow.

I'm using ruby on rails 3 and carrierwave as my upload handler.

Is this even possible or am I only really going to be able to remove white backgrounds?

like image 353
hadees Avatar asked Mar 13 '12 19:03

hadees


People also ask

How do you remove the background of a picture and make it transparent?

Add a transparent area to a picture You can create a transparent area in most pictures. Select the picture that you want to create transparent areas in. Click Picture Tools > Recolor > Set Transparent Color.

How do I remove the background from a vector image?

Click the Direct Selection tool (arrow) or Object and then click Expand in the dropdown menu. This will bring up the anchor points in your Vector and convert it into a shape. Click on and select the background parts you want to get rid of. Press Delete.


1 Answers

For removing white backgrounds from images, following is a bash script using imagemagick :

#!/bin/bash

# pass the image path, image name and threshold(used as a fuzz factor) to the bash script
IMGPATH=$1
IMGNAME=$2
THRESHOLD=$3

# start real
convert ${IMGPATH}${IMGNAME} \( +clone -fx 'p{0,0}' \)  -compose Difference  -composite   -modulate 100,0  +matte  ${IMGPATH}${IMGNAME}_difference.png

# remove the black, replace with transparency
convert ${IMGPATH}${IMGNAME}_difference.png -bordercolor white -border 1x1 -matte -fill none -fuzz 7% -draw 'matte 1,1 floodfill' -shave 1x1 ${IMGPATH}${IMGNAME}_removed_black.png
composite  -compose Dst_Over -tile pattern:checkerboard ${IMGPATH}${IMGNAME}_removed_black.png ${IMGPATH}${IMGNAME}_removed_black_check.png

# create the matte 
convert ${IMGPATH}${IMGNAME}_removed_black.png -channel matte -separate  +matte ${IMGPATH}${IMGNAME}_matte.png

# negate the colors
convert ${IMGPATH}${IMGNAME}_matte.png -negate -blur 0x1 ${IMGPATH}${IMGNAME}_matte-negated.png

# eroding matte(to remove remaining white border pixels from clipped foreground)
convert ${IMGPATH}${IMGNAME}_matte.png -morphology Erode Diamond ${IMGPATH}${IMGNAME}_erode_matte.png

# you are going for: white interior, black exterior
composite -compose CopyOpacity ${IMGPATH}${IMGNAME}_erode_matte.png ${IMGPATH}${IMGNAME} ${IMGPATH}${IMGNAME}_finished.png

#remove white border pixels
convert ${IMGPATH}${IMGNAME}_finished.png -bordercolor white -border 1x1 -matte -fill none -fuzz  ${THRESHOLD}% -draw 'matte 1,1 floodfill' -shave 1x1 ${IMGPATH}${IMGNAME}_final.png

#deleting extra files
rm ${IMGPATH}${IMGNAME}_difference.png
rm ${IMGPATH}${IMGNAME}_removed_black.png
rm ${IMGPATH}${IMGNAME}_removed_black_check.png
rm ${IMGPATH}${IMGNAME}_matte.png
rm ${IMGPATH}${IMGNAME}_matte-negated.png
rm ${IMGPATH}${IMGNAME}_finished.png

I was facing a problem removing white border pixels from the resulting image. Eroding the binary mask and shaving the remaining pixels solves the problem.


Source : convert white to transparent

like image 111
jahackbeth Avatar answered Sep 26 '22 01:09

jahackbeth