R で作成された PDF 画像を LaTeX で使う

バウンディングボックスとは

EPS ファイルにあるバウンディングボックスの値は,PDF ファイルや PNG, JPG ファイルにはない。そのため,画像の大きさを確認して,手作業でバウンディングボックスの値を確定しないといけない。でも,foo.bb というファイルがあれば,そして,foo.bb を自動作成できればそのような手間が省ける。

追記2010.04.09 Unix には BoundingBox の値を画像ファイルから抜き出す命令がある。Windows 用の命令もあるらしい。参考

foo.bb の中身は簡単なもの。以下のようなものの3行目だけが必要。

%%Title: ./foo.jpg
%%Creator: Rebb Version 0.0.1
%%BoundingBox: 0 0 410 350
%%CreationDate: Fri Apr 16 14:34:24 2010

河童の屁が補足 2010/04/14
R が作る pdf に対しては ebb は以下のようなエラーメッセージを出すので,

Version of PDF file (1.4) is newer than version limit specification.
Can't handle file type for file named average.pdf

ebb のソースを弄ってもよいけど R による ebb を書いて見る。ついでに,png と jpg にも対応させる

ebb <- function(fn, verbose=TRUE) # .bb を作りたいファイルを fn に指定
{
	getSizePng <- function(fn)
	{
		w.h <- NA
		input <- file(fn, open="rb")
		pass <- readBin(input, raw(), 16)
		if (all(pass[1:4] == c("89", "50", "4e", "47"))) {
			w.h <- readBin(input, integer(), 2, size=4, endian="big")
		}
		close(input)
		return(w.h)
	}

	getSizeJpeg <- function(fn)
	{
		h.w <- NA
		input <- file(fn, open="rb")
		SOI <- readBin(input, raw(), 2) # ff d8
		if (all(SOI==c("ff", "d8"))) {
			repeat {
				SOF0 <- readBin(input, raw(), 2)
				length <- readBin(input, integer(), size=2, endian="big")
				if (SOF0[1] == "ff" && ("c0" <= SOF0[2] && SOF0[2] <= "c3")) {
					accuracy <- readBin(input, integer(), size=1)
					h.w <- readBin(input, integer(), 2, size=2, endian="big")
					break
				}
				pass <- readBin(input, raw(), length-2)
			}
		}
		close(input)
		return(h.w[2:1])
	}

	getSizePdf <- function(fn)
	{
		x <- readLines(fn)
		suppressWarnings(line.no <- grep("MediaBox", x))
		if (length(line.no) > 0) {
			for (i in line.no) {
				bb <- x[i]
				if (!grepl("/MediaBox *\\[", bb)) {
					bb <- paste(bb, x[i+1])
				}
				bb <- gsub("\\[", " ", bb)
				bb <- gsub("\\]", " ", bb)
				bb <- unlist(strsplit(bb, " +"))
				j <- grep("MediaBox", bb)
				w.h <- as.integer(bb[j+3:4])
				return(w.h)
			}
		}
		stop(paste(fn, "のファイルのサイズは,わかんね〜な。"))
	}
	######################################
	if (file.exists(fn) == FALSE) {
		stop(paste(fn, "ってのは,見あたんね〜な。"))
	}
	file.bb <- sub(".(pdf|png|jpe*g)$", ".bb", fn, ignore.case=TRUE)
	if (file.exists(file.bb) == FALSE ||
		file.info(file.bb)$mtime < file.info(fn)$mtime) { # 対象ファイルとその .bb ファイルの更新日時をみて必要なら作成
		if (grepl(".pdf$", fn, ignore.case=TRUE)) {
			wh <- getSizePdf(fn)
		}
		else if (grepl(".png$", fn, ignore.case=TRUE)) {
			wh <- getSizePng(fn)
		}
		else if (grep(".jpe*g$", fn, ignore.case=TRUE)) {
			wh <- getSizeJpeg(fn)
		}
		if (verbose) cat(fn, ": ", wh, ", ", file.bb, "\n")
		writeLines(sprintf("%%%%Title: ./%s\n%%%%Creator: Rebb Version 0.0.1\n%%%%BoundingBox: 0 0 %d %d\n%%%%CreationDate: %s\n",
		   fn, wh[1], wh[2], date()), file.bb)
	}
}
# シュガーコート
ebbAll <- function(pattern="(.pdf|.png|.jpe*g)", ignore.case=TRUE, verbose=TRUE, ...)
{
	invisible(sapply(list.files(pattern=pattern, ignore.case=ignore.case), ebb, verbose=verbose))
}
# 使用法(作業ディレクトリ中のすべての pdf, png, jpg ファイルの .bb を作る)
ebbAll(verbose=FALSE)

トップ   編集 凍結 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2023-03-25 (土) 11:19:16