私は写真を撮り、指のジェスチャーで長方形を配置して、その上に長方形を描きたいと思っています。
画面を操作している間、すべてが正常に機能し、正しく表示されます。しかし、SDカードに長方形で画像を保存したい場合、正しい画像の背景を持つ画像を取得しますが、長方形が少し壊れています。誰かがそれらの一部を切り取ったように見えます。かつては長方形でしたが、がらくたのように見えたことがわかります。
私の質問はなぜですか?
キャンバスのビットマップを設定できないスレッドが原因で、すべてを1つのキャンバスに保存し、これをSDカードに保存するのに大きな問題がありました。2つのキャンバスを使用した後、私が言ったように機能していますが、長方形が壊れています. キャンバス上に基になるイメージ ビットマップなしで四角形を描画すると、四角形は正しく保存されます。私は本当にそれを取得しません。想像できることはすべて試しましたが、エラーは発生しません。
コード全体の短い例を投稿しようとしています:
public class Mark extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.mark);
p = new Panel(this);
frLayout = (FrameLayout)findViewById(R.id.preview);
frLayout.addView(p);
bitmap = BitmapFactory.decodeFile(image_path + "/img.jpg", options);
img = (ImageView) findViewById(R.id.img_capturedImage);
bitmapAll = Bitmap.createBitmap(bitmap.getWidth(),bitmap.getHeight(),Bitmap.Config.ARGB_8888);
save.setOnClickListener(new View.OnClickListener() {
try {
out = new FileOutputStream(file);
bitmapAll.compress(Bitmap.CompressFormat.JPEG, 100, out);
out.flush();
out.close();
MediaStore.Images.Media.insertImage(getContentResolver(),
file.getAbsolutePath(), file.getName(),
file.getName());
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
class Panel extends SurfaceView implements SurfaceHolder.Callback {
private TutorialThread _thread;
Canvas myCanvas;
public Panel(Context context) {
super(context);
getHolder().addCallback(this);
_thread = new TutorialThread(getHolder(), this);
setFocusable(true);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
synchronized (_thread.getSurfaceHolder()) {
switch(event.getAction() & MotionEvent.ACTION_MASK){
... save the coordinates for the rectangle ...
}
return true;
}
@Override
public void onDraw(Canvas canvas) {
myCanvas = new Canvas(bitmapAll);
Paint paint = new Paint();
myCanvas.drawBitmap(bitmap, 0, 0, paint);
canvas.drawBitmap(bitmap, 0, 0, paint);
paint.setXfermode(new PorterDuffXfermode(Mode.SRC_OVER));
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(3);
Rect rect;
for (...go over every saved rectangle ...) {
rect.set(...coordinates...);
canvas.drawRect(rect, paint);
myCanvas.drawRect(rect, paint);
}
}
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
// TODO Auto-generated method stub
}
public void surfaceCreated(SurfaceHolder holder) {
_thread.setRunning(true);
_thread.start();
}
public void surfaceDestroyed(SurfaceHolder holder) {
boolean retry = true;
_thread.setRunning(false);
while (retry) {
try {
_thread.join();
retry = false;
} catch (InterruptedException e) {
}
}
}
}
class TutorialThread extends Thread {
private SurfaceHolder _surfaceHolder;
private Panel _panel;
private boolean _run = false;
public TutorialThread(SurfaceHolder surfaceHolder, Panel panel) {
_surfaceHolder = surfaceHolder;
_panel = panel;
}
public void setRunning(boolean run) {
_run = run;
}
public SurfaceHolder getSurfaceHolder() {
return _surfaceHolder;
}
@Override
public void run() {
Canvas c;
while (_run) {
c = null;
try {
c = _surfaceHolder.lockCanvas(null);
synchronized (_surfaceHolder) {
_panel.onDraw(c);
}
} catch (Exception e) {
Log.e("Error", Log.getStackTraceString(e));
} finally {
if (c != null) {
_surfaceHolder.unlockCanvasAndPost(c);
}
}
}
}
}
}