LoginSignup
5
4

More than 5 years have passed since last update.

Haskell でサムネイル生成

Last updated at Posted at 2016-02-15

Haskell でサムネイルを生成するライブラリ thumbnailthumbnail-plus を評価してみました。

thumbnail

使い方はこんな感じです。

ThumbSample.hs
import qualified Data.ByteString.Lazy as LBI
import Graphics.Thumbnail (mkThumbnail', Thumbnail(..))

file :: FilePath
file = "img/original.jpg"

main :: IO ()
main = do
  jpeg <- LBI.readFile file
  Right thumb <- mkThumbnail' ((50, 50), (200, 200)) jpeg
  saveFile thumb "img/thumb1.jpg"

ByteString から Thumbnail を生成して、saveFile で任意の場所に保存するだけです。サムネイルのサイズは ((50, 50), (200, 200)) と指定していますが、これで幅と高さが 50px 〜 200px に収まるようなサムネイルが生成されます。

残念なのが、サムネイル生成時に JPEG Exif の Orientation を見てくれないので、元画像によってはサムネイルが横向きや逆さまになってしまうことです。

なおこのサンプルプログラムが依存しているライブラリは:

  • base
  • thumbnail
  • bytestring

です。

thumbnail-plus

使い方はこんな感じです。

ThumbPlusSample.hs
import Control.Monad.IO.Class (liftIO)
import Control.Monad.Trans.Resource (runResourceT)
import qualified Data.ByteString.Lazy as LBI
import Data.Default (def)
import Data.Either (either)
import Graphics.ThumbnailPlus ( CreatedThumbnails(..)
                              , createThumbnails
                              , Configuration(..)
                              , Size(..)
                              , Thumbnail(..)
                              )
import System.Directory (renameFile)

file :: FilePath
file = "img/original.jpg"

conf :: Configuration
conf = def { maxFileSize = 1024 * 1024 * 100
           , thumbnailSizes = [ ( Size 200 200
                                , Nothing
                                )
                              ]
           }

main :: IO ()
main = do
  jpeg <- LBI.readFile file
  runResourceT $ do
    CreatedThumbnails (_:[t]) _ <- createThumbnails conf file
    liftIO $ renameFile (thumbFp t) "img/thumb2.jpg"
  return ()

このライブラリは、使い勝手はあまり良くありません。その理由のひとつ目は、元画像のファイルサイズの最大値を maxFileSize で指定しなければならない点です。指定しない場合、デフォルトで 5MiB なのでちょっと高解像度で撮影した写真だとサイズオーバーになってサムネイルが生成できません。このサンプルでは指定していませんが、maxImageSize もデフォルトで 3000x3000 ピクセルなので、同様に高解像度で撮影した写真だとアウトです。

ふたつ目は、複数サイズのサムネイルを配列で指定して一気に生成できるようなインターフェイスになっているのですが、オリジナルサイズのサムネイルが常に生成されてしまう点です。場合によっては便利なのかもしれませんが、できれば指定したサイズだけを生成してもらいたいものです。このサンプルではオリジナルサイズは不要なのでリストの先頭を無視しています。

みっつ目は、サムネイルが勝手にテンポラリディレクトリに生成されてしまうことです。さらに生成されたファイルは /tmp/thumbnail-plus-71103/thumb-200x150-71103 のように拡張子が付いておらず、自前で拡張子を付与してあげなければなりません。さらにさらに、生成されたファイルのパーミッションは 600 だったりするので、別途 644 に変更してあげないとブラウザから読み込めません(サーバサイドの場合)。

そして、やはり JPEG Exif の Orientation がサムネイル生成時に無視されるので、サムネイルが回転してしまっていることがあります。

なおこのサンプルプログラムが依存しているライブラリは:

  • base
  • thumbnail-plus
  • bytestring
  • data-default
  • resourcet
  • transformers
  • directory

です。

まとめ

thumbnail がおすすめです。ただし、どちらでサムネイルを作成しても、サムネイルが回転してしまう問題があり、これは別記事 Haskell でサムネイル #2 で対策を検討することにします。

5
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
4