Converting Apple's Add To Wallet Images

Apple distributes their “Add to Wallet” images as SVGs which is great, but if you want to add it to an email or anything else that has issues with SVG files you’re going to need a PNG (to maintain transparency around the rounded corners). Unfortunately there are a LOT of these images needed to support the various languages.

a screenshot of a github pr with multiple apple wallet images

apple wallet images pr

Converting these to PNGs is not as easy as you’d hope.

Problems I encountered:

  1. imagemagick produces unusably bad images (mostly just black) even though it’s theoretically calling rsvg-convert under the covers and calling that directly works fine.
  2. inconsistent width and height
  3. extra transparent pixels on right and bottom edges

Here’s my solution with comments inline about what I learned along the way. It involves 2 scripts. The first one is in fish shell, just because that’s where i started but you should be able to convert to Bash or whatever you like to use pretty easily.

#!/usr/bin/env fish

for file in (find . -name "*.svg")
  set directory (dirname $file)
  set base_filename (basename $file .svg)
  set new_filename $directory/$base_filename.png
  # -z 10 add zoom. not because we need it bigger, but because
  # it looks WAY better when you add _any_ amount of zoom.
  # -w 884 because if i don't constrain width or height then
  # the results are too varied to apply a consistent cropping
  # percentage
  rsvg-convert -z 10 --keep-aspect-ratio -w 884 -o $new_filename $file
  # convert $new_filename -gravity NorthEast -crop WIDTHxHEIGHT $new_filename
  # image_size.rb is outputting the cropped "WIDTHxHEIGHT"
  convert $new_filename -gravity NorthEast -crop (image_size.rb (identify -ping -format '%w %h' $new_filename)) $new_filename

  # -crop results in foo-0.png foo-1.png foo-2.png (sometimes)
  #   and foo-3.png (sometimes)
  # what you want is in 0.png and the others are bits cropped off ?
  mv $directory/$base_filename-0.png $new_filename

  for n in (seq 1 3)
    # delete the unnecessary files. &> is redirecting STDERR to STDOUT
    # then shoving all to /dev/null because it doesn't ALWAYS generate
    # the -2  and -3 files ?!?!
    rm $directory/$base_filename-$n.png &> /dev/null
  git add $new_filename


With a constrained initial width plus a little scratchpad math i was able to figure out that cropping 0.7% from the width & 2.8% from the height (rounded up on both) seemed to get me “good enough” results.

It’s not perfect. Some still have 1 or 2 pixels of transparency at the bottom, and some are cropped a little too much along the bottom (thin grey border missing). But, I don’t want to manually edit 45 files for languages we don’t support anyway. I figure we can go back in and manually edit the handful that are imperfect.

#!/usr/bin/env ruby

# cropper for ... wallet things

initial_width, initial_height = ARGV[0].split(/\s+/).map{|x| x.to_i}
width_hundredth = (initial_width.to_f / 100)
height_hundredth = (initial_height.to_f / 100.0)

width_crop_percent = 0.7
height_crop_percent = 2.8 #2.58

new_width  = initial_width  - (width_crop_percent * width_hundredth).ceil
new_height = initial_height - (height_crop_percent * height_hundredth).ceil

puts "#{new_width}x#{new_height}"