Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Added the import_pixels() method for creating an Image object from a …

…string blob containing raw pixel data.
  • Loading branch information...
commit c407ebd8f27c2deb23597d27ad5447df3926eae0 1 parent 4395c97
@dicom dicom authored
Showing with 68 additions and 7 deletions.
  1. +33 −4 lib/mini_magick.rb
  2. +35 −3 test/image_test.rb
View
37 lib/mini_magick.rb
@@ -29,7 +29,7 @@ class Invalid < StandardError; end
class Image
# @return [String] The location of the current working file
- attr :path
+ attr_accessor :path
# Class Methods
# -------------
@@ -63,6 +63,34 @@ def from_blob(blob, ext = nil)
create(ext) { |f| f.write(blob) }
end
+ # Creates an image object from a binary string blob which contains raw pixel data (i.e. no header data).
+ #
+ # === Returns
+ #
+ # * [Image] The loaded image.
+ #
+ # === Parameters
+ #
+ # * [blob] <tt>String</tt> -- Binary string blob containing raw pixel data.
+ # * [columns] <tt>Integer</tt> -- Number of columns.
+ # * [rows] <tt>Integer</tt> -- Number of rows.
+ # * [depth] <tt>Integer</tt> -- Bit depth of the encoded pixel data.
+ # * [map] <tt>String</tt> -- A code for the mapping of the pixel data. Example: 'gray' or 'rgb'.
+ # * [format] <tt>String</tt> -- The file extension of the image format to be used when creating the image object. Defaults to 'png'.
+ #
+ def import_pixels(blob, columns, rows, depth, map, format="png")
+ # Create an image object with the raw pixel data string:
+ image = create(".dat", validate = false) { |f| f.write(blob) }
+ # Use ImageMagick to convert the raw data file to an image file of the desired format:
+ converted_image_path = image.path[0..-4] + format
+ argument = "-size #{columns}x#{rows} -depth #{depth} #{map}:#{image.path} #{converted_image_path}"
+ cmd = CommandBuilder.new("convert", argument) #Example: convert -size 256x256 -depth 16 gray:blob.dat blob.png
+ image.run(cmd)
+ # Update the image instance with the path of the properly formatted image, and return:
+ image.path = converted_image_path
+ image
+ end
+
# Opens a specific image file either on the local file system or at a URI.
#
# Use this if you don't want to overwrite the image file.
@@ -100,9 +128,10 @@ def from_file(file, ext = nil)
# by both #open and #read to create a new object! Ensures we have a good tempfile!
#
# @param ext [String] Specify the extension you want to read it as
+ # @param validate [Boolean] If false, skips validation of the created image. Defaults to true.
# @yield [IOStream] You can #write bits to this object to create the new Image
# @return [Image] The created image
- def create(ext = nil, &block)
+ def create(ext = nil, validate = true, &block)
begin
tempfile = Tempfile.new(['mini_magick', ext.to_s])
tempfile.binmode
@@ -111,7 +140,7 @@ def create(ext = nil, &block)
image = self.new(tempfile.path, tempfile)
- if !image.valid?
+ if validate and !image.valid?
raise MiniMagick::Invalid
end
return image
@@ -133,7 +162,7 @@ def initialize(input_path, tempfile = nil)
@path = input_path
@tempfile = tempfile # ensures that the tempfile will stick around until this image is garbage collected.
end
-
+
def escaped_path
"\"#{Pathname.new(@path).to_s}\""
end
View
38 test/image_test.rb 100755 → 100644
@@ -258,18 +258,18 @@ def test_issue_15
ensure
FileUtils.rm("test.gif")
end
-
+
# https://github.com/probablycorey/mini_magick/issues/37
def test_nonstandard_locale
original_lang = ENV["LANG"]
ENV["LANG"] = "fr_FR.UTF-8"
-
+
# This test should break
test_throw_on_openining_not_an_image
ensure
ENV["LANG"] = original_lang
end
-
+
def test_poop
img = MiniMagick::Image.open(SIMPLE_IMAGE_PATH)
img.gravity "Center"
@@ -287,4 +287,36 @@ def test_throw_format_error
end
image.destroy!
end
+
+ def test_import_pixels_default_format
+ columns = 325
+ rows = 200
+ depth = 16 # 16 bits (2 bytes) per pixel
+ map = 'gray'
+ pixels = Array.new(columns*rows) {|i| i}
+ blob = pixels.pack("S*") # unsigned short, native byte order
+ image = Image.import_pixels(blob, columns, rows, depth, map)
+ assert image.valid?
+ assert_equal "png", image[:format].downcase
+ assert_equal columns, image[:width]
+ assert_equal rows, image[:height]
+ image.write(CURRENT_DIR + "imported_pixels_image.png")
+ end
+
+ def test_import_pixels_custom_format
+ columns = 325
+ rows = 200
+ depth = 16 # 16 bits (2 bytes) per pixel
+ map = 'gray'
+ format = 'jpeg'
+ pixels = Array.new(columns*rows) {|i| i}
+ blob = pixels.pack("S*") # unsigned short, native byte order
+ image = Image.import_pixels(blob, columns, rows, depth, map, format)
+ assert image.valid?
+ assert_equal format, image[:format].downcase
+ assert_equal columns, image[:width]
+ assert_equal rows, image[:height]
+ image.write(CURRENT_DIR + "imported_pixels_image." + format)
+ end
+
end
Please sign in to comment.
Something went wrong with that request. Please try again.