繁体   English   中英

从另一个活动读取位图 -> 空图像

[英]Reading Bitmap from another activity -> Empty Image

背景:给一些背景⇒应用程序应该简单地向用户显示一个区域(SignatureActivity / SignatureCanvasView)来放置签名。 我找到了一个片段,它非常适合绘制。

问题:尝试在 MainActivity 中检索位图以在 ImageView 中显示它会显示一个空图像。 同时写入检索到的位图会创建一个 png 文件,该文件几乎是空的,因为它甚至没有背景颜色。

这就是它在 MainActivity 中的完成方式:

    private void insertSignature(){
        ivSign.setImageBitmap(signature);
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data){
        if(requestCode == SIGNATURE_REQUEST){
            if(resultCode == RESULT_OK){
                signature = BitmapFactory.decodeByteArray(data.getByteArrayExtra("SignatureBitmap"), 0, data.getByteArrayExtra("SignatureBitmap").length);
                //signature = (Bitmap) getIntent().getParcelableExtra("SignatureBitmap");
                if(signature != null){
                    insertSignature();
                    Log.e("ActivityResult: ", "SignatureActivity finished with RESULT_OK");
                }
            }else if(resultCode == RESULT_CANCELED){
                Log.e("ActivityResult: ", "SignatureActivity was cancelled");
            }else{
                Log.e("ActivityResult", "Unknown activity result!");
            }
        }

    }

那是视图(SignatureCanvasView)的代码,它维护签名功能:

public class SignatureCanvasView extends View {
    public int width;
    public int height;
    private Bitmap mBitmap;
    private Canvas mCanvas;
    private Path mPath;
    Context context;
    private Paint mPaint;
    private float mX, mY;
    private static final float TOLERANCE = 5;

    public SignatureCanvasView(Context c, AttributeSet attrs) {
        super(c, attrs);
        context = c;

        // we set a new Path
        mPath = new Path();

        // and we set a new Paint with the desired attributes
        mPaint = new Paint();
        mPaint.setAntiAlias(true);
        mPaint.setColor(Color.BLACK);
        mPaint.setStyle(Paint.Style.STROKE);
        mPaint.setStrokeJoin(Paint.Join.ROUND);
        mPaint.setStrokeWidth(2f);
    }

    public byte[] getBitmap() {
        ByteArrayOutputStream stream = new ByteArrayOutputStream();
        mBitmap.compress(Bitmap.CompressFormat.PNG, 100, stream);
        byte[] byteArray = stream.toByteArray();

        return byteArray;
    }


    // override onSizeChanged
    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);

        // your Canvas will draw onto the defined Bitmap
        mBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
        mCanvas = new Canvas(mBitmap);
    }

    // override onDraw
    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        // draw the mPath with the mPaint on the canvas when onDraw
        canvas.drawPath(mPath, mPaint);
    }

    // when ACTION_DOWN start touch according to the x,y values
    private void startTouch(float x, float y) {
        mPath.moveTo(x, y);
        mX = x;
        mY = y;
    }

    // when ACTION_MOVE move touch according to the x,y values
    private void moveTouch(float x, float y) {
        float dx = Math.abs(x - mX);
        float dy = Math.abs(y - mY);
        if (dx >= TOLERANCE || dy >= TOLERANCE) {
            mPath.quadTo(mX, mY, (x + mX) / 2, (y + mY) / 2);
            mX = x;
            mY = y;
        }
    }

    public void clearCanvas() {
        mPath.reset();
        invalidate();
    }

    // when ACTION_UP stop touch
    private void upTouch() {
        mPath.lineTo(mX, mY);
    }

    //override the onTouchEvent
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        float x = event.getX();
        float y = event.getY();

        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                startTouch(x, y);
                invalidate();
                break;
            case MotionEvent.ACTION_MOVE:
                moveTouch(x, y);
                invalidate();
                break;
            case MotionEvent.ACTION_UP:
                upTouch();
                invalidate();
                break;
        }
        return true;
    }
}

在 SignatureActivity 中调用 SignatureCanvasView 的 getBitmap() 方法将其作为额外的,在完成之前:

public class SignatureActivity extends AppCompatActivity {
    //...
    public void Save(){
        this.getIntent().putExtra("SignatureBitmap",scw.getBitmap());
        setResult(RESULT_OK,this.getIntent());
        finish();
    }
    //...
}

我感谢任何解决问题的提示和建议。

您绘制Pathcanvas附有SignatureCanvasView ,而不是附加与画布Bitmap mBitmap

// override onDraw
@Override
protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);
    // draw the mPath with the mPaint on the canvas when onDraw
    // canvas.drawPath(mPath, mPaint);
    boolean drawPathTwice = true;
    if (drawPathTwice) {
        canvas.drawPath(mPath, mPaint); // this will be visible to user
        mCanvas.drawPath(mPath, mPaint);// draw path onto canvas attached with mBitmap
        // drawing path 2 times(wasting resources).
    } else {
        mCanvas.drawPath(mPath, mPaint);  // draw path onto canvas attached with mBitmap
        canvas.drawBitmap(mBitmap, 0, 0, null);
        // we have drawn path onto bitmap canvas, so view's canvas will be
        // empty, to give touch feedback we can draw our bitmap containing
        // path onto view's canvas.
    }
}

更好的选择是拥有一个类范围布尔值,它将控制位图上的绘制(您可以在 upTouch() 方法中将其设置为 true)。

@Override
protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);
    canvas.drawPath(mPath, mPaint);

    if (drawOnBitmap) {  // this code will be executed only on ACTION_UP
        // event
        mCanvas.drawPath(mPath, mPaint);  // draw path onto canvas attached with mBitmap
        drawOnBitmap = false;
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM