2014年4月30日水曜日

[Java] Apache POIで指定した範囲の中心に画像を貼り付けようとして挫折

下記の条件でExcelファイル(※2007以降の.xlsx形式)に画像を貼り付ける。(だいぶ限定的…)

1.画像を貼り付けるセル範囲が指定されている。
2.画像は指定された範囲内で、アスペクト比を保ったまま最大化する。
3.範囲は任意だが、指定された範囲のセルはすべて同じ幅であり、
 かつ指定された範囲のセルはすべて同じ高さとする。


こんな感じ。(水平・垂直方向が逆のケースもあり)


結論から言うと、完全にアスペクト比を保ったままの最適化は出来なかった。

上記図で言うmarginは画像貼り付け先の開始位置をずらしつつ、オフセットを指定することで構成されるが、オフセットの指定はint型でしか行えないことによる。(必要なオフセットは当然、小数の場合もある)

単純なことだが、それに気付くまでの軌跡は↓。。

// 画像とセル範囲のアスペクト比を比較
double imgRatio = (orgImgWidth / (double)orgImgHeight);
double cellRangeRatio = (cellRangeWidth / (double)cellRangeHeight);

// 高さを最大化し、水平方向位置を計算する
if (imgRatio < cellRangeRatio) {
  // 貼り付けられる画像の幅
  double imgWidth = (orgImgWidth * (cellRangeHeight / (double)orgImgHeight));

  // 余白の幅
  double margin = (cellRangeWidth - imgWidth) / 2 ;
  int offsetCol = (int)(margin /  cellWidth);
  imgStartCol = rcol1 + offsetCol;
  imgEndCol = rcol2 - offsetCol;
  int offset = (int)(XSSFShape.EMU_PER_PIXEL * (margin  %  cellWidth));
  dx1 = offset;
  dx2 = offset;

// 横を最大化し、垂直方向位置を計算する
} else if (imgRatio > cellRangeRatio) {
  // 貼り付けられる画像の高さ
  double imgHeight = (orgImgHeight * (cellRangeWidth / (double)orgImgWidth));

  // 余白の高さ
  double margin = (cellRangeHeight - imgHeight) / 2 ;
  int offsetRow = (int)(margin /  cellWidth);
  imgStartRow = rrow1 + offsetRow;
  imgEndRow = rrow2 - offsetRow;
  int offset =  (int)(XSSFShape.EMU_PER_PIXEL * (margin  %  cellHeight));
  dy1 = offset;
  dy2 = offset;
}

【環境】

 POI 3.10
 Java SE7

2014年4月29日火曜日

[JavaScript] 画像の一部を範囲選択してぼかす(もしくはその他の加工を行う)

ブラウザに表示される画像の一部を範囲選択してぼかす機能を実装したい。
まだ試してないけども下記なんかを組み合わせて実現できそう。

1.範囲選択

Jcrop - Deep Liquid - 

2.ぼかし(その他の加工も多く用意されている)

Pixastic: JavaScript Image Processing Library - 


と思ったらPixasticはIEじゃ動かない的な一文が。

Pixastic works by utilizing the HTML5 Canvas element which provides access to raw pixel data, thereby opening up for more advanced image effects. This is where the "experimental" part comes into play. Canvas is only supported by some browsers and unfortunately Internet Explorer is not one of them. 
とはいえこれがいつ書かれた文書なのか良くわからないので今度ちゃんと試してみる。





そういえば、
画像加工用のライブラリは大量にあるみたいだけど、範囲を指定して加工できるものはあまり無いような気がした。

2014年4月28日月曜日

BloggerのテンプレートにSyntaxHighlighter組み込んだ。

タイトル以上の情報なし。


下記サイトを参考に入れてみた。

Pirates of 富山湾: Bloggerにソースコードをきれいに載せる「SyntaxHighlighter」

なんか面倒なのかな…と思っていたけど3分ぐらいで設定終わって、即使えるようになった。
ありがとうございます。

[Java] Apache POI XSSFClientAnchor でoffset を指定して画像を貼り付ける

初POI。
EXCEL(.xlsx)ファイルに画像を貼り付ける際の offset の指定に苦戦。

画像の位置指定は XSSFClientAnchor クラスを用いて行う。
設定方法は下記の2通りが可能。

1.create時に位置指定を行う。

XSSFClientAnchor anchor = XSSFDrawing.createAnchor(
                          dx1, dy1, dx2, dy2, col1, row1, col2, row2);

2.create後に位置指定を行う。

XSSFClientAnchor anchor = XSSFCreationHelper.createClientAnchor();
anchor.setDx1(dx1);
anchor.setDy1(dy1);
anchor.setDx2(dx2);
anchor.setDy2(dy2);
anchor.setCol1(col1);
anchor.setRow1(row1);
anchor.setCol2(col2);
anchor.setRow2(row2);

※XSSFDrawing クラスに引数無しのcreateAnchorメソッドは無い模様。

開始位置・終了位置の指定

XSSFAnchor.setCol , setRowでcolumn・rowをそれぞれ指定する。
注意点としては、指定したセルの最右下の座標から開始されること。
anchor.setCol1(1);
anchor.setRow1(1);
anchor.setCol2(4);
anchor.setRow2(4);

と指定すると

と出力される。

また、左辺と上辺は罫線上に描画され、右辺と下辺は罫線に重ならない。


オフセットの指定

XSSFClientAnchor#setDx1, setDy1, setDx2, setDy2 で指定する。
これら setter の引数はjavadocには
the x coordinate within the first cell.
とあり、int型の引数が要求されているが、ピクセルなのかポイントなのかわからない。
適当な数字を入れても挙動の法則がわからなかったので、
The offsets are measured in EMUs (english metric units). There are 12700 emus in a point , see EMU_PER_PIXEL and EMU_PER_POINT constants in the XSSFShape class. 

To position a rectange with given width and height at a point (x,y) 
you need to transform all coordinates to Excel coordinate system, i.e 

x1 --> col1 + dx1 
y1 --> row1 + dy1 
x2 --> col2 + dx2 
y2 --> row2 + dy2 
EMUという単位で指定する、とのこと。
この数字はXSSFShape クラスに定義されており、1ポイント=12700EMU、1ピクセル=9525となっている。

その為、setColやsetRowで指定した開始位置から10ピクセルのoffsetを作りたい時は
setDx1(XSSFShape.EMU_PER_PIXEL * 10);
とすれば良い模様。


指定するdx1, dy1, dx2, dy2 はそれぞれ下記のようにオフセットを構成する。




【環境】

POI 3.10
Java SE7

【参考】

apache poi の HSSFClientAnchor について。 - 人工無脳が作りたかった
POI - User - How to calculate location of the shape in Excel 2007?
POI - Dev - Re: Anchor type for images in Excel