その他
    ホーム 技術発信 DoRuby 【ruby】そうなんだ! 画像の情報を取得するためのgemふたつ
    【ruby】そうなんだ! 画像の情報を取得するためのgemふたつ
     

    【ruby】そうなんだ! 画像の情報を取得するためのgemふたつ

    この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

    ユーザーからの画像投稿を扱うシステムを作る場合、画像のサイズや向き、位置情報などを取得したいときがあると思います。

    またrubyにおいて画像の情報を取得するgemは様々ありますが、gemごとにどのような違いがあるか分かりません。

    そこで特にオーソドックスなgem
    ・mini_exiftool
    ・exifr
    を使って、下↓の写真の情報を取得してみます。

    enter image description here

    1. mini_exiftool
    ・実行ファイル

    require 'mini_exiftool'
    t = MiniExiftool.new "ファイル名"
    p t.to_hash
    

    ・出力結果

     {
            "ExifToolVersion"=>10.31,
            "FileSize"=>"2.2 MB",
            "FileModifyDate"=>2016-10-31 18:16:03 +0900,
            "FileAccessDate"=>2016-10-31 18:42:27 +0900,
            "FileInodeChangeDate"=>2016-10-31 18:16:03 +0900,
            "FilePermissions"=>"rw-r--r--", "FileType"=>"JPEG",
            "FileTypeExtension"=>"jpg",
            "MIMEType"=>"image/jpeg",
            "ExifByteOrder"=>"Big-endian (Motorola, MM)",
            "Make"=>"Apple",
            "Model"=>"iPhone 6",
            "Orientation"=>"Rotate 90 CW",
            "XResolution"=>72,
            "YResolution"=>72,
            "ResolutionUnit"=>"inches",
            "Software"=>"10.0.2",
            "ModifyDate"=>2016-10-27 09:44:46 +0900,
            "YCbCrPositioning"=>"Centered",
            "ExposureTime"=>(1/507),
            "FNumber"=>2.2,
            "ExposureProgram"=>"Program AE",
            "ISO"=>32, "ExifVersion"=>"0221",
            "DateTimeOriginal"=>2016-10-27 09:44:46 +0900,
            "CreateDate"=>2016-10-27 09:44:46 +0900,
            "ComponentsConfiguration"=>"Y, Cb, Cr, -",
            "ShutterSpeedValue"=>(1/507),
            "ApertureValue"=>2.2,
            "BrightnessValue"=>7.94202454,
            "ExposureCompensation"=>0,
            "MeteringMode"=>"Multi-segment",
            "Flash"=>"Off, Did not fire",
            "FocalLength"=>"4.2 mm",
            "SubjectArea"=>"1631 1223 1795 1077",
            "SubSecTimeOriginal"=>707,
            "SubSecTimeDigitized"=>707,
            "FlashpixVersion"=>100,
            "ColorSpace"=>"sRGB",
            "ExifImageWidth"=>3264,
            "ExifImageHeight"=>2448,
            "SensingMethod"=>"One-chip color area",
            "SceneType"=>"Directly photographed",
            "ExposureMode"=>"Auto",
            "WhiteBalance"=>"Auto",
            "FocalLengthIn35mmFormat"=>"29 mm",
            "SceneCaptureType"=>"Standard",
            "LensInfo"=>"4.15mm f/2.2",
            "LensMake"=>"Apple",
            "LensModel"=>"iPhone 6 back camera 4.15mm f/2.2",
            "GPSLatitudeRef"=>"North",
            "GPSLongitudeRef"=>"East",
            "GPSAltitudeRef"=>"Above Sea Level",
            "GPSTimeStamp"=>"00:44:46",
            "GPSSpeedRef"=>"km/h",
            "GPSSpeed"=>0,
            "GPSImgDirectionRef"=>"True North",
            "GPSImgDirection"=>190.0831889,
            "GPSDestBearingRef"=>"True North",
            "GPSDestBearing"=>190.0831889,
            "GPSDateStamp"=>"2016:10:27",
            "GPSHPositioningError"=>"25 m",
            "Compression"=>"JPEG (old-style)",
            "ThumbnailOffset"=>2014,
            "ThumbnailLength"=>10251,
            "ImageWidth"=>3264,
            "ImageHeight"=>2448,
            "BitsPerSample"=>8,
            "ColorComponents"=>3,
            "YCbCrSubSampling"=>"YCbCr4:2:0 (2 2)",
            "Aperture"=>2.2,
            "GPSAltitude"=>"73.7 m Above Sea Level",
            "GPSDateTime"=>2016-10-27 00:44:46 UTC,
            "GPSLatitude"=>"35 deg 39' 59.74\" N",
            "GPSLongitude"=>"139 deg 42' 14.82\" E",
            "GPSPosition"=>"35 deg 39' 59.74\" N, 139 deg 42' 14.82\" E",
            "ImageSize"=>"3264x2448",
            "Megapixels"=>8.0,
            "RunTimeSincePowerUp"=>"5 days 21:26:54",
            "ScaleFactor35efl"=>7.0, "ShutterSpeed"=>(1/507),
            "SubSecCreateDate"=>2016-10-27 09:44:46 +0900,
            "SubSecDateTimeOriginal"=>2016-10-27 09:44:46 +0900,
            "ThumbnailImage"=>"(Binary data 10251 bytes, use -b option to extract)",
            "CircleOfConfusion"=>"0.004 mm",
            "FOV"=>"63.7 deg",
            "FocalLength35efl"=>"4.2 mm (35 mm equivalent: 29.0 mm)",
            "HyperfocalDistance"=>"1.82 m",
            "LightValue"=>12.9
            }
    

    大量のデータが取得できました。ソフトウェアのバージョンまで取得しています。
    一方で出力までに時間がかかり、初めて実行した時は10秒ほどかかりました。

    また、

    "ExifImageWidth"=>3264,
    "ExifImageHeight"=>2448,
    "ImageSize"=>"3264x2448"
    

    のように重複してそうなデータもあるようです。

    2. exifr

    ・実行ファイル

    require ‘exifr’
    @exif = EXIFR::JPEG.new(‘IMG_1546.JPG’)
    p @exif.to_hash

    ・出力結果

    {
        :width=>3264,
        :height=>2448,
        :bits=>8,
        :comment=>nil,
        :make=>"Apple",
        :model=>"iPhone 6",
        :orientation=>#<EXIFR::TIFF::Orientation:RightTop(6)>,
        :x_resolution=>(72/1), :y_resolution=>(72/1),
        :resolution_unit=>2,
        :software=>"10.0.2",
        :date_time=>2016-10-27 09:44:46 +0900,
        :ycb_cr_positioning=>1,
        :exposure_time=>(1/507),
        :f_number=>(11/5),
        :exposure_program=>2,
        :iso_speed_ratings=>32,
        :date_time_original=>2016-10-27 09:44:46 +0900,
        :date_time_digitized=>2016-10-27 09:44:46 +0900,
        :shutter_speed_value=>(1/506),
        :aperture_value=>2.2,
        :brightness_value=>(25891/3260),
        :exposure_bias_value=>(0/1),
        :metering_mode=>5,
        :flash=>16,
        :focal_length=>(83/20),
        :subject_area=>[1631, 1223, 1795, 1077],
        :subsec_time_original=>"707",
        :subsec_time_digitized=>"707",
        :color_space=>1,
        :pixel_x_dimension=>3264,
        :pixel_y_dimension=>2448,
        :sensing_method=>2,
        :exposure_mode=>0,
        :white_balance=>0, :focal_length_in_35mm_film=>29,
        :scene_capture_type=>0,
        :gps_latitude_ref=>"N",
        :gps_latitude=>[(35/1), (39/1), (2987/50)],
        :gps_longitude_ref=>"E",
        :gps_longitude=>[(139/1), (42/1), (741/50)],
        :gps_altitude_ref=>"\x00",
        :gps_altitude=>(4943/67),
        :gps_time_stamp=>[(0/1), (44/1), (46/1)],
        :gps_speed_ref=>"K",
        :gps_speed=>(0/1),
        :gps_img_direction_ref=>"T",
        :gps_img_direction=>(109678/577),
        :gps_dest_bearing_ref=>"T",
        :gps_dest_bearing=>(109678/577),
        :gps_date_stamp=>"2016:10:27"
    }
    

    画像の情報のほかに、カメラやiPhone本体の情報も取得されました。
    MIMETypeが出力されていないですが、そもそもexifrはJPEGとTIFFのファイルしか対応していないようです。
    出力までの速さはmini_exiftoolに比べて早かったです。

    まとめ
    【共通】
    画像の幅・高さ
    写真を撮影した日時・位置情報
    カメラの設定や部品の情報

    【mini_tool】

    • 実行時間が長い
    • pngもgifも使える
    • キャメルケース
    • オブジェクト形式
    • 情報が豊富

    【exifr】

    • 実行時間が短い
    • png、gifなどに未対応
    • スネークケース
    • シンボル形式
    • データの名前がが分かりやすい

    参考にさせていただきましたm(_ _)m
    画像ファイルからEXIF情報を取り出す
    RubyでEXIFを見る。mini_exiftoolを入れる。