0

I have a png with the outline of an irregularly shaped object which I want to turn into a mask. I need to floodfill the interior with black, and then swap black and white. It's 8-bit grayscale, with values of 0 and 255 only.

enter image description here

I can't fill the exterior, leaving the interior white, since the outline itself must be included in the positive area. (Assume the array values for black, white, and red are already defined.)

    mask =  Vips::Image.new_from_file(fl)
    mask = mask.draw_flood(black, center_x, center_y, :equal => true) * -1

This returns an all-black raster. Boo hoo! This works, but is ugly and inefficient.

    mask = mask.draw_flood(black, center_x, center_y, :equal => true)
    mask = mask.draw_flood(red, 0, 0, :equal => true)
    mask = mask.draw_flood(white, center_x, center_y, :equal => true)
    mask = mask.draw_flood(black, 0, 0, :equal => true)

Does anyone know a more elegant solution? Thanks for any guidance.

Robert Schaaf
  • 81
  • 1
  • 3

1 Answers1

0

You've got it, it's the * -1 that's messing you up. That'll make a float image with each pixel * -1 (obviously), so your white areas will become -255. When you save as PNG again, the image will be cast back to uint8, the negatives will be chopped off and you'll just see zero.

You really want 255 - x, but Ruby won't let you have a number on the left of a binary image operator, so you need to write x * -1 + 255.

You can go one better: ruby-vips has #invert, which calculates (image-format-max - image-pixel) and doesn't change the numeric format. In this case that means (255 - x) and staying as uint8.

So this:

x = Vips::Image.new_from_file "flood1.png"
x = x.draw_flood 0, 256, 256, equal: true
x = x.invert
x.write_to_file "x.png"

Makes this:

enter image description here

(the edges are all screwy -- your example was anti-aliased by the time I got it, sorry)

jcupitt
  • 10,213
  • 2
  • 23
  • 39
  • Thanks a lot, user894763! This worked like a charm. In this project I've used convert, Imagemagick, rmagick, vips, and java, both raw and Graph2D. Up until two weeks ago, I had no knowledge of any of them, and it's a lot of documentation to get through. A lot of picking and choosing, like a cafeteria. Wouldn't it be great if their raster classes were interoperable? – Robert Schaaf Jul 21 '18 at 02:19
  • Wow, that's quite a smorgasbord of software. libvips is the best, obviously, hehe. I do medical imaging and there packages often don't even interoperate at the file format level :( DICOM has as many flavours as there are scanner manufacturers. – jcupitt Jul 21 '18 at 09:21