イメージビューに大きな(約2000x2000px)ビットマップを表示するアプリに取り組んでいます。この画像は、ユーザーがピンチしてズームして詳細を表示できるため、それほど大きくする必要があります。アプリはその画像に円を描くことができなければならず、また、円を付けずに画像だけを表示することもできなければなりません。私は2つのレイヤーを使用していましたが、問題はメモリです.2k x 2k pxは約16MBのメモリであり、いくつかの円を描くためだけに別のビットマップ(別の16MB)を作成することは私の意見では無意味です. 画像に単純なプリミティブを描画し、プリミティブ (私の場合は円) なしで表示できる方法はありますか? どうにかして、変更されたピクセルまたは sth のみを保存するにはどうすればよいでしょうか。ありがとう!
2 に答える
これらの円を描画するために別の 2000x2000 を作成する必要はありませんBitmap
。円を「事前レンダリング」してから、それを描く場所を選択してください。
Canvas
ズーム機能などがあるため、「大きな」画像を に描いているという前提で作業しています。
そうでない場合は、SurfaceView のonDraw(Canvas canvas)
メソッドをオーバーライドして、 SurfaceView Canvas
. 私はあなたがそれを持っていると仮定しているので、その部分については深く掘り下げませんが、そうでない場合、その関数の実装は次のようになります:
//Overriding SurfaceView onDraw(Canvas canvas)
@Override
protected void onDraw(Canvas surfaceCanvas) {
if(canvas == null) return; //No Canvas? No point in drawing then.
surfaceCanvas.drawColor(Color.BLACK);
//Draw your 'big' image on the SurfaceView Canvas
insertYourBigImageDrawingFunctionHere(surfaceCanvas);
//Now draw your circles at their correct positions...
insertCircleDrawingFunctionHere(surfaceCanvas);
}
SurfaceView キャンバスにアクセスできるようになったので、描画方法を正確に選択できます。たとえば円のように...
Canvas
以下で使用されている複数の ' (surfaceCanvas と circleCanvas) に注意してください。Canvas は一種の「アプリ/アクティビティ全体の 1 つの Canvas」実装だと思っていましたが、そうではありません。「」は自由に作成Canvas
してください。これは、ビットマップに描画するためのツールの単なるインスタンスです。これは私にとって大きな啓示であり、ビットマップの構成方法をより確実に制御できるようになりました。
public void myCircleDrawingFunction(Canvas surfaceCanvas){
//Make a new Bitmap for your circle
Bitmap.Config conf = Bitmap.Config.ARGB_4444;
tinyCircleBMP = Bitmap.createBitmap(10,10, conf);
//Make a new canvas using that Bitmap as the source...
Canvas circleCanvas = new Canvas(cacheBmp);
//Now, perform your drawing on the `Canvas`...
Paint p = new Paint();
circleCanvas.drawCircle(5, 5, 5, p);
//Now the `Bitmap` has a circle on it, draw the `Bitmap` on the `SufaceView Canvas`
surfaceCanvas.drawBitmap(tinyCircleBMP, 10, 10, p);
//Replace the '10's in the above function with relevant coordinates.
}
明らかに、円は「大きな」画像と同じサイズ/位置で描画されなくなるため、「大きな」画像とは異なる方法でズーム/パンします。「大きな」画像の現在の縮尺と位置を考慮して、各円の位置を変換する方法を検討する必要があります。
たとえば、画像が 200% にズームインされていて、大きな画像の左から 100 ピクセルの位置に円が表示される場合、次のようにピクセル値を乗算してズームを考慮する必要があります。
(疑似コード):
drawCircleAtX = Bitmap.left * BitmapZoomFactor
キャンバス API を使用している場合 (そうでない場合はお勧めします)? その場合は、キャンバスに画像を描画してから、表示前に同じキャンバスの上にプリミティブ形状を描画するだけです。このようにして、いくつかの基本的なデータ型で円の位置の参照を保持し、ユーザーが動き回ったりズームしたりするとそれらをスケーリングするだけで、フレームごとに円をどこに描画するかがわかります。