icon.rake 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. ICONS_DIR = 'public'
  2. ORIGINAL_IMAGE = 'media/huginn-icon-square.svg'
  3. desc "Generate site icons from #{ORIGINAL_IMAGE}"
  4. task :icons => 'icon:all'
  5. namespace :icon do
  6. # iOS
  7. task :all => :ios
  8. [
  9. 57, 114,
  10. 60, 120, 180,
  11. 72, 144,
  12. 76, 152,
  13. ].each do |width|
  14. sizes = '%1$dx%1$d' % width
  15. filename = "apple-touch-icon-#{sizes}.png"
  16. icon = File.join(ICONS_DIR, filename)
  17. file icon => ORIGINAL_IMAGE do |t|
  18. puts "Generating #{t.name}"
  19. convert_image t.source, t.name, width: width
  20. end
  21. task :ios => icon
  22. end
  23. # Android
  24. task :all => :android
  25. android_icons = [
  26. 36, 72, 144,
  27. 48, 96, 192,
  28. ].map do |width|
  29. sizes = '%1$dx%1$d' % width
  30. filename = "android-chrome-#{sizes}.png" % width
  31. icon = File.join(ICONS_DIR, filename)
  32. file icon => ORIGINAL_IMAGE do |t|
  33. puts "Generating #{t.name}"
  34. convert_image t.source, t.name, width: width, round: true
  35. end
  36. task :android => icon
  37. {
  38. src: "/#{filename}",
  39. sizes: sizes,
  40. type: 'image/png',
  41. density: (width / 48.0).to_s,
  42. }
  43. end
  44. manifest = File.join(ICONS_DIR, 'manifest.json')
  45. file manifest => __FILE__ do |t|
  46. puts "Generating #{t.name}"
  47. require 'json'
  48. json = {
  49. name: 'Huginn',
  50. icons: android_icons
  51. }
  52. File.write(t.name, JSON.pretty_generate(json))
  53. end
  54. task :android => manifest
  55. end
  56. require 'mini_magick'
  57. def convert_image(source, target, options = {}) # width: nil, round: false
  58. ext = target[/(?<=\.)[^.]+\z/] || 'png'
  59. original = MiniMagick::Image.open(source)
  60. result = original
  61. result.format ext
  62. if width = options[:width]
  63. result.thumbnail '%1$dx%1$d>' % width
  64. else
  65. width = result[:width]
  66. end
  67. if options[:round]
  68. radius = (Rational(80, 512) * width).round
  69. mask = MiniMagick::Image.create(ext) { |tmp| result.write(tmp) }
  70. mask.mogrify do |image|
  71. image.alpha 'transparent'
  72. image.background 'none'
  73. image.fill 'white'
  74. image.draw 'roundrectangle 0,0,%1$d,%1$d,%2$d,%2$d' % [width, radius]
  75. end
  76. result = result.composite(mask) do |image|
  77. image.alpha 'set'
  78. image.compose 'DstIn'
  79. end
  80. end
  81. result.strip
  82. result.write(target)
  83. end