Module: Okmain::Sampler
- Defined in:
- lib/okmain/sampler.rb
Constant Summary collapse
- MAX_SAMPLE_SIZE =
250_000
Class Method Summary collapse
- .compute_block_size(total) ⇒ Object
-
.sample(input) ⇒ Object
Returns [pixels, width, height] where pixels is an Array of [L, a, b] triples.
Class Method Details
.compute_block_size(total) ⇒ Object
54 55 56 57 58 59 60 61 62 |
# File 'lib/okmain/sampler.rb', line 54 def compute_block_size(total) return 1 if total <= MAX_SAMPLE_SIZE bs = Math.sqrt(total.to_f / MAX_SAMPLE_SIZE).ceil # Round up to multiple of 4 remainder = bs % 4 bs += (4 - remainder) if remainder != 0 bs end |
.sample(input) ⇒ Object
Returns [pixels, width, height] where pixels is an Array of [L, a, b] triples.
12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 |
# File 'lib/okmain/sampler.rb', line 12 def sample(input) image = if input.is_a?(Vips::Image) input else Vips::Image.new_from_file(input.to_s, access: :sequential) end # Flatten alpha to white background image = image.flatten(background: [255, 255, 255]) if image.has_alpha? # Convert to scRGB (linear float) for accurate block averaging image = image.colourspace(:scrgb) total = image.width * image.height block_size = compute_block_size(total) if block_size > 1 image = image.shrink(block_size, block_size) end width = image.width height = image.height # Extract float pixel data [r, g, b] in linear space floats = image.write_to_memory.unpack("f*") bands = image.bands pixel_count = width * height pixels = Array.new(pixel_count) i = 0 while i < pixel_count offset = i * bands r = floats[offset] g = floats[offset + 1] b = floats[offset + 2] pixels[i] = Oklab.linear_rgb_to_oklab(r, g, b) i += 1 end [pixels, width, height] end |