SurfaceViewでのBitmap描画がViewでの描画に比べて画質が悪い(?)

990 views
Skip to first unread message

hdk

unread,
Mar 30, 2010, 8:47:45 AM3/30/10
to 日本Androidの会
もりと申します。初めて投稿いたします。
早速質問で恐縮ですが、ご教示いただければ幸いです。

bitmapを表示するサンプルアプリを下記の2パターンで作ってみましたところ、
一部端末(大半がエミュレータですが)上では画質に違いが出てきてしまい、
どのように対応すべきか悩んでおります。

■実装方式(エラー処理など一部割愛いたします)
(1)Viewを継承したクラス内のonDraw(Canvas)内での描画
import android.content.Context;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.view.View;

public class MainView extends View{

public MainView(Context context){
super(context);
}

protected void onDraw(Canvas canvas){
canvas.drawBitmap
(BitmapFactory.decodeResource
(this.getResources(), R.drawable.hoge), 0, 0, null);
}
}

(2)SurfaceViewを継承したクラス内のSurfaceHolderからCanvasを取得しての描画
import android.content.Context;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.view.SurfaceHolder;
import android.view.SurfaceView;

public class MainSurface extends SurfaceView
implements Runnable, SurfaceHolder.Callback{

private Thread mThread = null;

public MainSurface(Context context){
super(context);
this.getHolder().addCallback(this);
}

public void surfaceCreated(SurfaceHolder arg0){
mThread = new Thread(this);
mThread.start();
}

public void surfaceDestroyed(SurfaceHolder arg0){
mThread = null;
}

public void run(){
Canvas canvas = null;
while(mThread != null){
try{
canvas = this.getHolder().lockCanvas();
if(canvas != null){
canvas.drawBitmap
(BitmapFactory.decodeResource
(this.getResources(), R.drawable.hoge), 0, 0,
null);
}
}
finally{
if(canvas != null)
this.getHolder().unlockCanvasAndPost(canvas);
}
}
}
}

■端末の種類(エミュレータはいずれもlist targetで表示されるName)
(A)Android 1.5 ←エミュレータ
(B)Android 1.6 ←エミュレータ
(C)X10 ←エミュレータ(XPERIA)
(D)JN-DK01 (Beta version) ←エミュレータ
(E)HT-03A ←実機(ファームウェアVer1.6)

■結果
(A) ⇒ (1)(2)ともに画質変わらず
(B) ⇒ (1)(2)ともに画質変わらず
(C) ⇒ (2)の画質が劣化、(1)ではきれいに表示される細かい文字がつぶれる感じ
(D) ⇒ (2)の画質が劣化、(1)ではきれいに表示される細かい文字がつぶれる感じ
(E) ⇒ (1)(2)ともに画質変わらず


上記のような結果となりました。
これ以外にもPaintでのアンチエイリアスの指定など色々検討してみましたが、
根本の分かれ道がSurfaceViewを使うか否かでしたので割愛いたしました。

SurfaceViewを利用する場合、何か欠けているものがありますでしょうか。

よろしくお願いいたします。

hdk

unread,
Mar 31, 2010, 7:56:09 AM3/31/10
to 日本Androidの会
お世話になっております。もりです。
自己レスとなりますが、SSを掲載いたしました。

http://picasaweb.google.co.jp/107999937759319349085/AndroidSS#
※外部リンクです

自分の実装に問題があるのだとは思いますが、
何かお知恵をお貸しいただければ幸いです。

根本で全然違う、とかもあればご指摘ください。。

mizmit1222

unread,
Mar 31, 2010, 9:43:52 PM3/31/10
to 日本Androidの会
みずのです。

Androidは色々なデバイスのサイズと解像度に対応するために
densityという考え方をとっています。

Xperia/IS01はhigh densityですので、対応したリソースを別に
用意する必要があります。詳しくは
http://d.android.com/guide/practices/screens_support.html

また、ボタンなど勝手に伸縮してほしい画像については、
9patchというツールでリソースを用意します。

このあたり、詳しい方にフォローいただけると幸いです。

ではでは。

hdk

unread,
Apr 1, 2010, 12:57:44 AM4/1/10
to 日本Androidの会
みずの様

お世話になっております。もりです。
ご回答いただきましてありがとうございました。
非常に参考になり、問題解決に至りました。

しっかり把握できていなかった部分でお恥ずかしい限りですが、
いただいた情報を元にやってみたことをまとめてご報告いたします。
既出のこととは思いますがご容赦ください。


(1)targetSdkVersionの調整

・1.5(Level 3)までのアプリケーションは、必然的に
[HVGA (320x480) resolution on a 3.2" screen]のスクリーンのみをサポートする
・1.6(Level 4)以降のアプリケーションは、デフォルトでは
すべてのスクリーンサイズ、すべての密度をサポートする(限定することも可能)

⇒SdkVersionごとに得られる選択肢を最大化するため、下記のように記述しました。

AndroidManifest.xml
<manifest...
<uses-sdk android:minSdkVersion="3"
android:targetSdkVersion="4" />
</manifest>


(2)supports-screensの調整

私の場合は「できるだけ広く細かく見せる」のが狙いでしたので、
(1)の時点で各端末を狙い通りに制御できるようになりました。
したがって、実際にはこの要素を指定はしておりません。

※以前まで、targetSdkVersionを調整しない私の状況では、下記設定と同等でした。
AndroidManifest.xml
<manifest...
<supports-screens android:smallScreens="false"
android:normalScreens="true"
android:largeScreens="false"
android:anyDensity="false" />
</manifest>

※今回、targetSdkVersionを4(以上)にした場合では、下記設定と同等となるようです。
<supports-screens android:smallScreens="true"
android:normalScreens="true"
android:largeScreens="true"
android:anyDensity="true" />


9patchの情報もありがとうございました。
こちらも確認いたします。

今後ともよろしくお願いいたします。

Reply all
Reply to author
Forward
0 new messages