描画を削除せずに、カスタムカラーピッカーから選択した色でキャンバスの背景を設定する方法を見つけようとしています。キャンバスに描画してpngとして保存できるアプリケーションを作成しようとしています。しかし、現在のキャンバスに新しい背景を設定すると、すべての描画が消えてしまいます。私はこのようなものを使用しています:
mCanvas.drawColor(picker.getColor());
物事を機能させる方法はありますか?
描画を削除せずに、カスタムカラーピッカーから選択した色でキャンバスの背景を設定する方法を見つけようとしています。キャンバスに描画してpngとして保存できるアプリケーションを作成しようとしています。しかし、現在のキャンバスに新しい背景を設定すると、すべての描画が消えてしまいます。私はこのようなものを使用しています:
mCanvas.drawColor(picker.getColor());
物事を機能させる方法はありますか?
質問に対する回答はすべて正しい方向を示しています。背景色のブロックと前景の描画を別々のレイヤーに分離し、それらをマージしてから、全体を.pngファイルに保存する必要があります。これは、Adobe Photoshopワークフローも設計されている方法です...考えてみると、それは理にかなっています。たとえば、MsPaintのようなソフトウェアを考えてみましょう。レイヤーを使用しないため、フラッドフィルアルゴリズムなどに依存する必要があります。バックグラウンドの変更にリモートで似た何かを(不完全な方法ではありますが)達成します...
このようなことを実装する1つの方法は、2つの異なるビットマップに裏打ちされた2つのCanvasオブジェクトをインスタンス化することです。最初のCanvas-Bitmapペアは前景での描画に使用され、2番目のCanvas-Bitmapペアはマージされたレイヤーの描画(つまり、前景描画+背景カラーブロック)に使用されます。次に、2番目のビットマップは、保存する必要があるときに.pngファイルに保存されるものです。このように、最初のCanvas-Bitmapペアは前景情報を保存します。これは、背景色を変更する必要がある場合でも破棄されません。操作が行われるたびに、レイヤーを2番目のCanvas-Bitmapペアにマージできるため、気まぐれで保存できる正しいコンテンツを含むビットマップが常に存在します。
これは、この方法論を明確にするために作成したカスタムビューです。指を使用してタッチスクリーンに青い線を描くために使用される単純なビューを実装し、完全な実装に固有の不要なコードの複雑さなしに背景色の変更を示すために、その指のXY位置に応じて背景色を変更しますカラーホイール/メニュー/とりわけ:
package com.epichorns.basicpaint;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Point;
import android.graphics.Paint.Style;
import android.view.View;
public class PaintView extends View{
Bitmap mMergedLayersBitmap=null; //Note: this bitmap here contains the whole of the drawing (background+foreground) to be saved.
Canvas mMergedLayersCanvas=null;
Bitmap mBitmap = null; //bitmap onto which we draw our stuff
Canvas mCanvas = null; //Main canvas. Will be linked to a .bmp file
int mBackgroundColor = 0xFF000000; //default background color
Paint mDefaultPaint = new Paint();
Paint mDrawPaint = new Paint(); //used for painting example foreground stuff... We draw line segments.
Point mDrawCoor = new Point(); //used to store last location on our PaintView that was finger-touched
//Constructor: we instantiate 2 Canvas-Bitmap pairs
public PaintView(Context context, int width, int height) {
super(context);
mMergedLayersBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
mMergedLayersCanvas = new Canvas(mMergedLayersBitmap);
mBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
mCanvas = new Canvas(mBitmap);
}
//Change background color
public void changeColor(int newColor){
mBackgroundColor = newColor;
invalidate(); //refresh view: this will indirectly invoke onDraw soon afterwards
}
//Called by user of PaintView in order to start a painting "stroke" (finger touching touch-screen): stores the
//location of the finger when it first touched the screen
public void startDraw(int x, int y, int radius, int color){
mDrawPaint.setColor(color);
mDrawPaint.setStyle(Style.STROKE);
mDrawPaint.setStrokeWidth(radius);
mDrawCoor.x = x;
mDrawCoor.y = y;
}
//Called by user of PaintView when finger touching touch-screen is moving (must be called after a startDraw,
//as the latter initializes a couple of necessary things)
public void continueDraw(int x, int y){
mCanvas.drawLine(mDrawCoor.x, mDrawCoor.y, x, y, mDrawPaint);
mDrawCoor.x = x;
mDrawCoor.y = y;
invalidate(); //refresh view: this will indirectly invoke onDraw soon afterwards
}
//Merge the foreground Canvas-Bitmap with a solid background color, then stores this in the 2nd Canvas-Bitmap pair.
private void mergeLayers(){
mMergedLayersCanvas.drawColor(mBackgroundColor);
mMergedLayersCanvas.drawBitmap(mBitmap, 0, 0, mDefaultPaint);
}
@Override
public void onDraw(Canvas canvas){
mergeLayers();
canvas.drawBitmap(mMergedLayersBitmap, 0, 0, mDefaultPaint);
}
}
このビューをテストするために、PaintView
クラスを使用するテストアクティビティを次に示します。これらのファイルは両方ともAndroidプロジェクトで自給自足であるため、手間をかけずに実際のデバイスでテストできます。
package com.epichorns.basicpaint;
import android.app.Activity;
import android.graphics.Color;
import android.os.Bundle;
import android.util.Log;
import android.view.Display;
import android.view.MotionEvent;
import android.view.View;
import android.widget.LinearLayout;
import com.epichorns.basicpaint.PaintView;
public class BasicPaintActivity extends Activity {
PaintView mPaintView=null;
LinearLayout mL = null;
boolean mIsDrawing=false;
int mBackgroundColor = 0xFF000000;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Display display = getWindowManager().getDefaultDisplay();
final float dispWidth = (float)display.getWidth();
final float dispHeight = (float)display.getHeight();
mPaintView = new PaintView(this, display.getWidth(), display.getHeight());
mPaintView.changeColor(mBackgroundColor);
mPaintView.setOnTouchListener(new View.OnTouchListener(){
public boolean onTouch(View v, MotionEvent event) {
if(event.getAction()==MotionEvent.ACTION_DOWN){
mPaintView.startDraw((int)event.getX(), (int)event.getY(), 6, 0x806060FF);
mIsDrawing=true;
return true;
}
else if(event.getAction()==MotionEvent.ACTION_UP){
mIsDrawing=false;
return true;
}
else if(event.getAction()==MotionEvent.ACTION_MOVE){
if(mIsDrawing){
//To demonstrate background change, change background color depending on X-Y position
int r = (int)(255f*event.getX()/dispWidth);
int g = (int)(255f*event.getY()/dispHeight);
mBackgroundColor = Color.argb(0xFF, r,g, 0x00);
Log.d("DEBUG1", "Color channels: (r, g) = ("+String.valueOf(r)+", "+String.valueOf(g)+")");
mPaintView.changeColor(mBackgroundColor);
//now, draw stuff where finger was dragging...
mPaintView.continueDraw((int)event.getX(), (int)event.getY());
return true;
}
else{
return false;
}
}
return false;
}
});
setContentView(mPaintView);
}
}
色を描くと、絵の上に色が描かれます。色を描いてから、他のすべてのものをもう一度描く必要があります。
canvas.drawARGB(a,r,g,b) を使用すると、明確に機能します
キャンバスで変更する場合は、invalidate を呼び出してこれらの変更を画面に適用する必要があります。また、invalidate を呼び出すと、onDraw()
メソッドが呼び出されます。
カラーピッカーからキャンバスの背景色だけを変更したい場合は、色の値を変数に保存し、変数を保存した直後に無効化を呼び出します。今すぐonDraw()
呼び出してキャンバスの背景を変更setBackgroundColor(color variable)
しonDraw()
、必要なものをすべて描画します
背景が別の色である限り、次のことができます。
for (x...)
for (y...)
if (bitmap.getPixel(x,y) == oldBackgroundColor)
bitmap.setPixel(x,y,newBackgroundColor)
または、コンテンツをオフスクリーン ビットマップに描画し、背景を描画してからオフスクリーンを実際のビットマップに描画することもできます。そうすれば、次の 2 段階描画が行われるときに使用される背景色を変更できます。