Чтение растрового изображения из другого занятия -> Пустое изображение - PullRequest
0 голосов
/ 19 февраля 2020

Фон: Чтобы дать немного фона ⇒ приложение должно просто показать пользователю область (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;
    }
}

Метод GetBitmap () объекта SignatureCanvasView вызывается в SignatureActivity, чтобы добавить его как дополнительный, перед завершением:

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

Я ценю любые советы и предложения по решению проблемы.

1 Ответ

1 голос
/ 20 февраля 2020

Вы рисуете Path на canvas, прикрепленном 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.
    }
}

Лучшим вариантом будет иметь логическую область видимости класса, которая будет управлять рисованием на растровом изображении (вы можете установить значение true в методе upTouch ()).

@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;
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...