1

I have and app with gems image_processing and ruby-vips.

I need to create white backgrounded image 1920x1920, add some black text there and write it to tempfile.

How can I do this with code?

Molfar
  • 1,411
  • 3
  • 18
  • 49

1 Answers1

2

It's a little fiddly. In plain ruby-vips you could write:

#!/usr/bin/ruby

require "vips"

# make the background

# make a one-pixel image, 8-bit, white (255), monochrome (b_w means black and 
# white)
image = (Vips::Image.black(1, 1) + 255).
  cast("uchar").
  copy(interpretation: :b_w)

# expand up to the size we need ... libvips can do this very quickly
image = image.embed(0, 0, 1920, 1080, extend: :copy)

# make the text image ... this will be a GA image (grey plus alpha)

# "text" makes an image with 0 for the background and 255 for the text, so we 
# can use it as the alpha
alpha = Vips::Image.text("Hello, world!", dpi: 600)

# we want black text, so put black in the G of our GA image
g = Vips::Image.black(alpha.width, alpha.height)

# put the text alpha and colour layer together ... again, tag as a monochrome
# image
txt = g.bandjoin(alpha).
  copy(interpretation: :b_w)

# composite the text on to the white background
final = image.composite(txt, "over", x: 100, y: 100)

final.write_to_file("x.png")

And run to make this:

enter image description here

With image_processing, you'd put something like that into a utility method and run it as part of your chain of operations.

You can make text images in a similar way: call text to make the alpha, then add a block of solid colour as the RGB. For example:

#!/usr/bin/ruby
  
require 'vips'

alpha = Vips::Image.text("", dpi: 600)
# make an image matching alpha, where each pixel has the specified value
rgb = alpha.new_from_image([10, 20, 100])
image = rgb.bandjoin(alpha)
puts "writing to x.png ..."
image.write_to_file "x.png"

To make:

enter image description here

You don't need to use a plain RGB block, of course, you could do something like:

#!/usr/bin/ruby
  
require 'vips'

alpha = Vips::Image.text("", dpi: 600)
rgb = (1..3).map {|i| Vips::Image.worley(alpha.width, alpha.height, seed: i)}
image = Vips::Image.bandjoin(rgb + [alpha])
puts "writing to x.png ..."
image.write_to_file "x.png"

To make:

enter image description here

text has a lot of other features. See:

https://www.rubydoc.info/gems/ruby-vips/Vips/Image#text-class_method

https://libvips.github.io/libvips/API/current/libvips-create.html#vips-text

jcupitt
  • 10,213
  • 2
  • 23
  • 39