diff --git a/lib/vips/image.rb b/lib/vips/image.rb index ea8b1af..f4d9ccf 100644 --- a/lib/vips/image.rb +++ b/lib/vips/image.rb @@ -41,6 +41,10 @@ module Vips attach_function :vips_image_get_height, [:pointer], :int attach_function :vips_image_get_bands, [:pointer], :int + enum :vips_band_format, [:notset, -1, :uchar, :char, :ushort, :short, :uint, :int, :float, :complex, :double, :dpcomplex] + attach_function :vips_format_sizeof, [:vips_band_format], :int64 + attach_function :vips_image_get_data, [:pointer], :pointer + if Vips.at_least_libvips?(8, 5) attach_function :vips_image_get_fields, [:pointer], :pointer attach_function :vips_image_hasalpha, [:pointer], :int @@ -1231,6 +1235,19 @@ def to_a to_enum.to_a end + # Return a read-only pointer to the pixel data, if possible. + # + # @return [FFI::Pointer] pointer to the pixel data + def read_ptr + copy = copy_memory + ptr = Vips.vips_image_get_data copy + raise Vips::Error if ptr.null? + + ptr.instance_variable_set(:@vips_reference, copy) + + ptr.slice(0, width * height * bands * Vips.vips_format_sizeof(format)) + end + # Return the largest integral value not greater than the argument. # # @return [Image] floor of image diff --git a/spec/image_spec.rb b/spec/image_spec.rb index 38fdb29..d50761f 100644 --- a/spec/image_spec.rb +++ b/spec/image_spec.rb @@ -127,6 +127,21 @@ expect { Vips::Image.new_from_memory_copy(data, 16, 16, 1, :uchar) }.to raise_error(Vips::Error) end + it "can load an image from a read pointer" do + image = Vips::Image.black(16, 16) + 128 + data = image.read_ptr + expect(data).to be_a(FFI::Pointer) + expect(data.size).to eq(1024) + + x = Vips::Image.new_from_memory data, + image.width, image.height, image.bands, image.format + + expect(x.width).to eq(16) + expect(x.height).to eq(16) + expect(x.bands).to eq(1) + expect(x.avg).to eq(128) + end + if has_jpeg? it "can save an image to a buffer" do image = Vips::Image.black(16, 16) + 128