Help us understand the problem. What is going on with this article?

scalaで外部コマンドを実行する

More than 5 years have passed since last update.

Scalaプログラムから ImageMagickを使ってリサイズなどを行う簡単な
ライブラリを作ったのでその一環でscala.sys.process を利用したので
それについて簡単にまとめます。

scala.sys.process パッケージについて

scala 2.9.0 から導入された
外部プロセスの実行、パイプ、リダイレクトなどが簡単にできる
外部プロセスを実行して、その結果をプログラム内で利用するのも簡単

REPLで動かしながら、scala.sys.processを試す


  • コマンドを実行して結果を標準出力(非同期)
scala> import scala.sys.process._
import scala.sys.process._

scala> Process("ls") run
res8: scala.sys.process.Process = scala.sys.process.ProcessImpl$SimpleProcess@15df07a5

scala> LICENSE
README
activator
activator-launch-1.3.2.jar
app
<略

  • 実行結果をString で取得したい場合は !!
scala> Process("ls") !!
res9: String =
"LICENSE
README
activator
activator-launch-1.3.2.jar
<略
"
  • 実行結果をコレクションで取得したりもできる
scala> Process("ls").lines.toList
res11: List[String] = List(LICENSE, README, activator, ...)
  • 同期処理でコマンド実行したい場合は、! (終了コードを返す)
scala> Process("ls") !
LICENSE
README
activator
<略
res10: Int = 0

・よりダイレクトな感じでも書ける
ProcessImplicits traitに stringToProcess, stringSeqToProcessとか暗黙の型変換が
定義されてて勝手にProcessBuilder型に変換してくれます。

scala> "ls" run
res13: scala.sys.process.Process = scala.sys.process.ProcessImpl$SimpleProcess@53f28395

scala> LICENSE
README
activator
activator-launch-1.3.2.jar
<略
  • パイプする #|
scala> "ps aux" #| "grep java" !
  • リダイレクト #>
scala> "ps aux" #> new File("hoge.txt") !

1つ目のコマンドが成功したら次のコマンド実行するとかも用意されてる -> #&&

ImageMagickで 16x16の画像をリサイズしてみる

convertコマンドについてはこちらを参照
http://www.envinfo.uee.kyoto-u.ac.jp/user/susaki/image/magick_process.html

scala> import scala.sys.process._

scala> import javax.imageio._

scala> import java.awt.image.BufferedImage

scala> import java.io.File

//processを使ってconvertコマンドを実行
scala> Process(Seq("/usr/local/bin/convert", "-geometry", "30x30", "-quality", "99", "./public/images/favicon.png", "./copied.png")).lines
res5: Stream[String] = Stream()


//ImageIOで画像がリサイズされてるか確認
scala> val src: BufferedImage = ImageIO.read(new File("./copied.png"))
src: java.awt.image.BufferedImage = BufferedImage@44755eae: type = 6 ColorModel: #pixelBits = 32 numComponents = 4 color space = java.awt.color.ICC_ColorSpace@f42d738 transparency = 3 has alpha = true isAlphaPre = false ByteInterleavedRaster: width = 30 height = 30 #numDataElements 4 dataOff[0] = 3

ByteInterleavedRaster: width = 30 height = 30 ってことでリサイズに成功しました

余談ではありますが、ImageMagickも良きにはからってくれて便利でした。
例えば、
200x100の画像で、サイズを400x300に指定した場合、
縦横比を保持したまま、指定したサイズの内接最大(今回は400x200)にリサイズしてくれます。
(縦横比を保持しないで指定サイズにリサイズとかその他も色々できる)

まとめ

簡単で便利でした。 シェル叩くのに近い感じの関数が色々用意されてていい感じです。


Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away