画像をきれいに縮小する方法を教えてください。
子供が描いたメロンの絵(250×250)を52×52に縮小したいのですが、下記のプロ
グラムを用いると、添付画像のdevice.pngにあるように(左上の絵)、汚い画像に
しかなりません。
melon2.png程度の原型をとどめている絵にしたいのですが、どのようにすれば
いいのでしょうか。自力でLanczosなどのアルゴリズムを実装するしか方法はな
いのでしょうか。
よろしくお願いします。
String toFile = "/sdcard/luarida/melon.png";
Bitmap bmp = BitmapFactory.decodeFile( toFile );
Bitmap workBmp = Bitmap.createBitmap( 300, 300, Bitmap.Config.ARGB_8888);
Canvas workcanvas = new Canvas( workBmp );
Paint paint = new Paint();
paint.setAntiAlias(true);
paint.setFilterBitmap(true);
paint.setDither(true);
int w = bmp.getWidth();
int h = bmp.getHeight();
workcanvas.drawBitmap(bmp, new Rect(0, 0, w, h), new Rect(0, 0, 52, 52),
paint);
workcanvas.drawBitmap(bmp, new Rect(0, 0, w, h), new Rect(0, 60, 250,
310), paint);
--
山本三七男 (Minao Yamamoto) ---------------- ハンドル:たろサ -----
E-Mail: taro...@gmail.com
メールを書いてから、いろいろと試していました。下記のソースのように、
matrix.postScale()を使う方法や、BitmapDrawableでsetAntiAliasを使う方法です。
いずれの場合も、同じような画像しか得られませんでした。結果画像を添付し
ます。プログラムにおかしなところがあるのでしょうか。
String refFile = "/sdcard/luarida/melon2.png";
String toFile = "/sdcard/luarida/melon.png";
Bitmap refbmp = BitmapFactory.decodeFile( refFile );
Bitmap bmp = BitmapFactory.decodeFile( toFile );
Bitmap workBmp = Bitmap.createBitmap( 300, 300, Bitmap.Config.ARGB_8888);
Canvas workcanvas = new Canvas( workBmp );
Matrix matrix = new Matrix();
float rx = 52f/250f;
float ry = 52f/250f;
matrix.postScale( rx, ry );
Bitmap scaledBitmap = Bitmap.createBitmap(bmp, 0, 0, bmp.getWidth(),
bmp.getHeight(), matrix,true);
BitmapDrawable bmd = new BitmapDrawable(bmp);
bmd.setAntiAlias(true);
bmd.setBounds(0,0,52,52);
//BitmapDrawableのアンチエイリアス有り
bmd.draw(workcanvas);
bmd.setAntiAlias(false);
bmd.setBounds(52,0,104,52);
//BitmapDrawableのアンチエイリアス無し
bmd.draw(workcanvas);
int a = scaledBitmap.getWidth();
int b = scaledBitmap.getHeight();
int w = bmp.getWidth();
int h = bmp.getHeight();
//matrix.postScaleを使って縮小
workcanvas.drawBitmap(scaledBitmap, new Rect(0, 0, a, b), new Rect(104,
0, 156, 52), null);
//ただの縮小
workcanvas.drawBitmap(bmp, new Rect(0, 0, w, h), new Rect(156, 0, 208,
52), null);
//参照
workcanvas.drawBitmap(refbmp, new Rect(0, 0, 52, 52), new Rect(208, 0,
208+52, 52 ), null);
//原寸大
workcanvas.drawBitmap(bmp, new Rect(0, 0, w, h), new Rect(0, 60, w,
60+h), null);
E-Mail: taro...@gmail.com
<img src=\""+image_uri+"\" width=\"210\" height=\"210\"/>
としている部分のwidthとheightを変更していただければ、それなりに縮小できると思います。
--
このメールは Google グループのグループ「日本Androidの会」の登録者に送られています。
このグループに投稿するには、android-g...@googlegroups.com にメールを送信してください。
このグループから退会するには、android-group-j...@googlegroups.com にメールを送信してください。
詳細については、http://groups.google.com/group/android-group-japan?hl=ja からこのグループにアクセスしてください。
松永さん、こんにちは。
> 私はWebViewで画像を読み込んで、
> 縮小等はHTMLやCSSで記述してみました。
こういうやり方もあるのですね。参考になります。ネット接続が必須になりま
すね。私の場合、wifi経由しか使っていないので、半常時接続状態なので、難し
いところです。
さっきのメール後、自力で、Lanczos処理を実装してみました。
処理が遅い割りには、結果がいまいちで、参ったなぁ・・・。という感じで
す。添付画像の右から2つ目です。
もう少し、悩んで見て、だめならあきらめます。
private Bitmap Lanczos(Bitmap bmp, float sc) {
int width = bmp.getWidth();
int height = bmp.getHeight();
int[] pixels = new int[width * height];
bmp.getPixels(pixels, 0, width, 0, 0, width, height);
int w = (int)((float)width*sc);
int h = (int)((float)height*sc);
int[] retpixels = new int[w * h];
int n = 3; // N値
int nx = n-1;
for (int y = 0; y < h; y++) {
for (int x = 0; x < w; x++) {
double x0 = (float)x/sc;
double y0 = (float)y/sc;
int xBase = (int)x0;
int yBase = (int)y0;
int color = 0;
// ランツォシュの処理範囲
if (xBase >= nx && xBase < width - n && yBase >= nx && yBase < height
- n) {
double[] color_element = new double[3];
color_element[0] = 0.0;
color_element[1] = 0.0;
color_element[2] = 0.0;
double w_total = 0.0;
// 周辺(a*2)^2画素を取得して処理
for (int i = -nx; i <= n; i++) {
for (int j = -nx; j <= n; j++) {
int xCurrent = xBase + i;
int yCurrent = yBase + j;
// 距離決定
double distX = Math.abs(xCurrent - x0);
double distY = Math.abs(yCurrent - y0);
// 重み付け
double weight = 0.0;
if (distX == 0.0) {
weight = 1.0;
} else if (distX < n) {
double dPIx = Math.PI*distX;
weight = (Math.sin(dPIx)*Math.sin(dPIx/n))/(dPIx*(dPIx/n));
} else {
continue;
}
if (distY == 0.0) {
;
} else if (distY < n) {
double dPIy = Math.PI*distY;
weight *= (Math.sin(dPIy)*Math.sin(dPIy/n))/(dPIy*(dPIy/n));
} else {
continue;
}
// 画素取得
int color_process = pixels[xCurrent+yCurrent*width];
for (int k = 0; k < 3; k++) {
color_element[k] += ((color_process >> k*8) & 0xff)*weight;
}
w_total += weight;
}
}
for (int i = 0; i < 3; i++) {
if (w_total != 0) color_element[i] /= w_total;
color_element[i] = (color_element[i] > 255) ? 255:
(color_element[i] < 0) ? 0: color_element[i];
color += (int)color_element[i] << i*8;
}
}
retpixels[x+y*w] = 0xff000000 + color;
}
}
Bitmap newbmp = Bitmap.createBitmap( w, h, Bitmap.Config.ARGB_8888);
newbmp.setPixels(retpixels, 0, w, 0, 0, w, h);
return newbmp;
}
(2011/01/06 1:48), Hiroshi Matsunaga wrote:
> たろサさん
>
> 松永と申します。
>
> スレの流れと完全に違う方法ですが、
> 最近私も画像の縮小やトリミングを試していたので、
> 参考になればと思い。返信させていただきます。
>
> 私はWebViewで画像を読み込んで、
> 縮小等はHTMLやCSSで記述してみました。
>
> http://matsuhilog.blogspot.com/2011/01/webview.html
> <http://matsuhilog.blogspot.com/2011/01/webview.html>にメモを取ってある
> のとサンプルソースのリンクがあるので、
> 参考にしていただければと思います。
>
> <img src=\""+image_uri+"\" width=\"210\" height=\"210\"/>
>
> としている部分のwidthとheightを変更していただければ、それなりに縮小できると思います。
>
>
> 以上です。
>
> 2011年1月6日1:13 たろサ <taro...@gmail.com <mailto:taro...@gmail.com>>:
> >> E-Mail: taros...@gmail.com <mailto:taros...@gmail.com>
> >>
> >> device.png
> >> 12K表示ダウンロード
> >>
> >> melon2.png
> >> 2K表示ダウンロード
> >
>
> --
> 山本三七男 (Minao Yamamoto) ---------------- ハンドル:たろサ -----
> E-Mail: taro...@gmail.com <mailto:taro...@gmail.com>
>
> --
> このメールは Google グループのグループ「日本Androidの会」の登録者に
> 送られています。
> このグループに投稿するには、android-g...@googlegroups.com
> <mailto:android-g...@googlegroups.com> にメールを送信してくだ
> さい。
> このグループから退会するには、android-group-
> japan+un...@googlegroups.com
> <mailto:android-group-japan%2Bunsu...@googlegroups.com> にメール
> を送信してください。
> 詳細については、http://groups.google.com/group/android-group-
> japan?hl=ja からこのグループにアクセスしてください。
>
>
>
>
> --
> Hiroshi Matsunaga
> email: hiroshi.82...@gmail.com
> <mailto:hiroshi.82...@gmail.com>
>
> --
> このメールは Google グループのグループ「日本Androidの会」の登録者に送ら
> れています。
> このグループに投稿するには、android-g...@googlegroups.com にメー
> ルを送信してください。
> このグループから退会するには、android-group-
> japan+un...@googlegroups.com にメールを送信してください。
> 詳細については、http://groups.google.com/group/android-group-japan?hl=ja
> からこのグループにアクセスしてください。
--
松永です。
失礼しました。
私が持っている実機はsimいれているので気がつかなかったです。
SDcardに保存してある画像も縮小できたので、お役に立てるかと思ったのですが、WebViewを利用する場合は、ネットワーク接続が必須だったのですね。。。
こちらこそ勉強になりました。
あれから、Bi-CubicとかBi-Linearとか、いろいろと実装して試していたので
すが、結局、考え方を変えました。
下記のようなアルゴリズムで、matrix.postScale()を使って縮小するプログラ
ムにしてみました。
これだと、高速で参照画像とほぼ同様の画像を得ることができました。
Matrix matrix = new Matrix();
float n = 4.0f;
float sc = (float)Math.exp(Math.log(52.0/250.0)/n);
matrix.postScale( sc, sc );
Bitmap scaledBitmap = Bitmap.createBitmap(bmp, 0, 0, bmp.getWidth(),
bmp.getHeight(), matrix,true);
for( int i=0; i<(int)n-1; i++ ){
scaledBitmap = Bitmap.createBitmap(scaledBitmap, 0, 0,
scaledBitmap.getWidth(), scaledBitmap.getHeight(), matrix,true);
}
すいません、お騒がせしました。
返信していただいた皆様、ありがとうございました。
> if (xBase>= nx&& xBase< width - n&& yBase>= nx&& yBase< height
> color_element[k] += ((color_process>> k*8)& 0xff)*weight;