Class: Magick::Image
- Inherits:
-
Object
- Object
- Magick::Image
- Includes:
- ClassLogging, Ownership, PerfStats
- Defined in:
- lib/httpthumbnailer/plugin/thumbnailer/service/magick.rb
Overview
WARNING: ‘raise’ is overwritten with an image operation method; use Kernel::raise instead!
Constant Summary
Constants included from Ownership
Ownership::BorrowingDestoryedError, Ownership::BorrowingNotOwnedError, Ownership::UseDestroyedError
Class Method Summary collapse
Instance Method Summary collapse
- #blur_region(x, y, w, h, radius, sigma) ⇒ Object
- #diagonal ⇒ Object
- #downsample(f) ⇒ Object
- #find_downsample_factor(max_width, max_height, factor = 1) ⇒ Object
- #float_to_offset(float_width, float_height, float_x = 0.5, float_y = 0.5) ⇒ Object
-
#get_for_inplace ⇒ Object
use this on image before doing in-place (like composite!) edit so borrowed images are not changed.
- #height ⇒ Object
- #pixelate_region(x, y, w, h, size) ⇒ Object
- #rel_to_diagonal(v) ⇒ Object
- #rel_to_px_box(x, y, width, height) ⇒ Object
- #rel_to_px_dim(width, height) ⇒ Object
- #rel_to_px_pos(x, y) ⇒ Object
- #render_on_background(background_color, width = nil, height = nil, float_x = 0.5, float_y = 0.5) ⇒ Object
- #render_rectangle(x, y, w, h, color) ⇒ Object
-
#resize_to_fill(width, height = nil, float_x = 0.5, float_y = 0.5) ⇒ Object
non coping version.
- #rotate(*args) ⇒ Object
-
#rotate_orig ⇒ Object
make rotate not to change image.page to avoid WTF moments.
- #width ⇒ Object
-
#with_background_color(color) ⇒ Object
helpers.
Methods included from Ownership
#borrow, #borrowed?, #get, #owned?
Class Method Details
.new_8bit(width, height, background_color = "none") ⇒ Object
21 22 23 24 25 26 27 28 29 30 |
# File 'lib/httpthumbnailer/plugin/thumbnailer/service/magick.rb', line 21 def self.new_8bit(width, height, background_color = "none") Magick::Image.new(width, height) { self.depth = 8 begin self.background_color = background_color rescue ArgumentError Kernel::raise Plugin::Thumbnailer::InvalidColorNameError.new(background_color) end } end |
Instance Method Details
#blur_region(x, y, w, h, radius, sigma) ⇒ Object
123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 |
# File 'lib/httpthumbnailer/plugin/thumbnailer/service/magick.rb', line 123 def blur_region(x, y, w, h, radius, sigma) # NOTE: we need to have bigger region to blure then the final regios to prevent edge artifacts # TODO: how do I calculate margin better? See: https://github.com/trevor/ImageMagick/blob/82d683349c7a6adc977f6f638f1b340e01bf0ea9/branches/ImageMagick-6.5.9/magick/gem.c#L787 margin = [3, radius, sigma].max.ceil mx = x - margin my = y - margin mw = w + margin mh = h + margin # limit the box with margin to available image size mx = 0 if mx < 0 my = 0 if my < 0 mw = width - mx if mw + mx > width mh = height - my if mh + my > height crop(mx, my, mw, mh, true).get do |work_space| work_space.blur_image(radius, sigma) end.get do |blur| blur.crop(x - mx, y - my, w, h, true) end.get do |blur| get_for_inplace do |orig| orig.composite!(blur, x, y, Magick::OverCompositeOp) end end end |
#diagonal ⇒ Object
204 205 206 |
# File 'lib/httpthumbnailer/plugin/thumbnailer/service/magick.rb', line 204 def diagonal @_diag ||= Math.sqrt(width ** 2 + height ** 2).ceil end |
#downsample(f) ⇒ Object
71 72 73 |
# File 'lib/httpthumbnailer/plugin/thumbnailer/service/magick.rb', line 71 def downsample(f) sample(columns / f, rows / f) end |
#find_downsample_factor(max_width, max_height, factor = 1) ⇒ Object
75 76 77 78 79 80 81 82 |
# File 'lib/httpthumbnailer/plugin/thumbnailer/service/magick.rb', line 75 def find_downsample_factor(max_width, max_height, factor = 1) new_factor = factor * 2 if columns / new_factor > max_width * 2 and rows / new_factor > max_height * 2 find_downsample_factor(max_width, max_height, factor * 2) else factor end end |
#float_to_offset(float_width, float_height, float_x = 0.5, float_y = 0.5) ⇒ Object
84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 |
# File 'lib/httpthumbnailer/plugin/thumbnailer/service/magick.rb', line 84 def float_to_offset(float_width, float_height, float_x = 0.5, float_y = 0.5) base_width = self.columns base_height = self.rows x = ((base_width - float_width) * float_x).ceil y = ((base_height - float_height) * float_y).ceil x = 0 if x < 0 x = (base_width - float_width) if x > (base_width - float_width) y = 0 if y < 0 y = (base_height - float_height) if y > (base_height - float_height) [x, y] end |
#get_for_inplace ⇒ Object
use this on image before doing in-place (like composite!) edit so borrowed images are not changed
11 12 13 14 15 16 17 18 19 |
# File 'lib/httpthumbnailer/plugin/thumbnailer/service/magick.rb', line 11 def get_for_inplace get do |image| if image.borrowed? yield image.copy else yield image end end end |
#height ⇒ Object
200 201 202 |
# File 'lib/httpthumbnailer/plugin/thumbnailer/service/magick.rb', line 200 def height rows end |
#pixelate_region(x, y, w, h, size) ⇒ Object
100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 |
# File 'lib/httpthumbnailer/plugin/thumbnailer/service/magick.rb', line 100 def pixelate_region(x, y, w, h, size) factor = 1.0 / size # what happens here # 1. get an required box cut form the image # 2. resize it down by fracto # 3. resize it back up by factor # 4. since we may end up with bigger image (due to size of the pixelate pixel) crop it to required size again # 5. composite over the original image in required position crop(x, y, w, h, true).get do |work_space| work_space.sample((factor * w).ceil, (factor * h).ceil) end.get do |image| image.sample(size) end.get do |image| image.crop(0, 0 , w, h, true) end.get do |image| get_for_inplace do |orig| orig.composite!(image, x, y, Magick::OverCompositeOp) end end end |
#rel_to_diagonal(v) ⇒ Object
192 193 194 |
# File 'lib/httpthumbnailer/plugin/thumbnailer/service/magick.rb', line 192 def rel_to_diagonal(v) (v * diagonal).ceil end |
#rel_to_px_box(x, y, width, height) ⇒ Object
188 189 190 |
# File 'lib/httpthumbnailer/plugin/thumbnailer/service/magick.rb', line 188 def rel_to_px_box(x, y, width, height) [*rel_to_px_pos(x, y), *rel_to_px_dim(width, height)] end |
#rel_to_px_dim(width, height) ⇒ Object
184 185 186 |
# File 'lib/httpthumbnailer/plugin/thumbnailer/service/magick.rb', line 184 def rel_to_px_dim(width, height) [(width * columns).ceil, (height * rows).ceil] end |
#rel_to_px_pos(x, y) ⇒ Object
180 181 182 |
# File 'lib/httpthumbnailer/plugin/thumbnailer/service/magick.rb', line 180 def rel_to_px_pos(x, y) [(x * columns).floor, (y * rows).floor] end |
#render_on_background(background_color, width = nil, height = nil, float_x = 0.5, float_y = 0.5) ⇒ Object
32 33 34 35 36 37 38 39 40 41 42 43 44 |
# File 'lib/httpthumbnailer/plugin/thumbnailer/service/magick.rb', line 32 def render_on_background(background_color, width = nil, height = nil, float_x = 0.5, float_y = 0.5) # default to image size width ||= self.columns height ||= self.rows # make sure we have enough background to fit image on top of it width = self.columns if width < self.columns height = self.rows if height < self.rows self.class.new_8bit(width, height, background_color).get do |background| background.composite!(self, *background.float_to_offset(self.columns, self.rows, float_x, float_y), Magick::OverCompositeOp) end end |
#render_rectangle(x, y, w, h, color) ⇒ Object
150 151 152 153 154 155 156 157 158 |
# File 'lib/httpthumbnailer/plugin/thumbnailer/service/magick.rb', line 150 def render_rectangle(x, y, w, h, color) get_for_inplace do |orig| gc = Magick::Draw.new gc.fill = color gc.rectangle(x, y, x + w - 1, y + h - 1) gc.draw(orig) orig end end |
#resize_to_fill(width, height = nil, float_x = 0.5, float_y = 0.5) ⇒ Object
non coping version
47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 |
# File 'lib/httpthumbnailer/plugin/thumbnailer/service/magick.rb', line 47 def resize_to_fill(width, height = nil, float_x = 0.5, float_y = 0.5) # default to square height ||= width return if width == columns and height == rows scale = [width / columns.to_f, height / rows.to_f].max get do |image| # this will comsume (destory) self just after resize image.resize((scale * columns).ceil, (scale * rows).ceil) end.get do |image| next if width == image.width and height == image.height image.crop(*image.float_to_offset(width, height, float_x, float_y), width, height, true) end end |
#rotate(*args) ⇒ Object
65 66 67 68 69 |
# File 'lib/httpthumbnailer/plugin/thumbnailer/service/magick.rb', line 65 def rotate(*args) out = rotate_orig(*args) out.page = Magick::Rectangle.new(out.columns, out.rows, 0, 0) out end |
#rotate_orig ⇒ Object
make rotate not to change image.page to avoid WTF moments
64 |
# File 'lib/httpthumbnailer/plugin/thumbnailer/service/magick.rb', line 64 alias :rotate_orig :rotate |
#width ⇒ Object
196 197 198 |
# File 'lib/httpthumbnailer/plugin/thumbnailer/service/magick.rb', line 196 def width columns end |
#with_background_color(color) ⇒ Object
helpers
162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 |
# File 'lib/httpthumbnailer/plugin/thumbnailer/service/magick.rb', line 162 def with_background_color(color) if color was = self.background_color begin begin self.background_color = color rescue ArgumentError Kernel::raise Plugin::Thumbnailer::InvalidColorNameError.new(color) end yield ensure self.background_color = was end else yield end end |