2016-11-16 95 views
0

我正在使用Android的Fingerpaint演示[1]來試驗Canvas和Bitmaps。我想在屏幕上繪製一個對象,並在屏幕旋轉後繼續繪製對象。 Fingerpaint演示會在屏幕旋轉後擦除屏幕 - 我想保留屏幕內容並隨屏幕一起旋轉屏幕。Android:爲什麼不能在旋轉屏幕後在畫布位圖上繪製?

用我的代碼,我可以旋轉屏幕和我繪製的圖像。但是我不能再爲位圖添加任何其他路徑標記。它變得像只讀位圖。有誰知道我是我做錯了什麼?

下面是我保存圖像並在旋轉後恢復的代碼。請注意,我將其保存爲一個字節數組PNG(可在的onSaveInstanceState()),然後創建從的onCreate(該字節數組的新位圖)(我認爲這是好?):

@Override 
public void onSaveInstanceState(Bundle savedInstanceState) { 
    Log.d("TAG", "Saving state..."); 
    ByteArrayOutputStream stream = new ByteArrayOutputStream(); 
    canvasView.mBitmap.compress(Bitmap.CompressFormat.PNG, 100, stream); 
    imageByteArray = stream.toByteArray(); 
    savedInstanceState.putSerializable("ByteArray", imageByteArray); 
    super.onSaveInstanceState(savedInstanceState); 
} 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    canvasView = new MyView(this); 
    setContentView(canvasView); 

    mPaint = new Paint(); 
    mPaint.setAntiAlias(true); 
    mPaint.setDither(true); 
    mPaint.setColor(0xFF00FF00); 
    mPaint.setStyle(Paint.Style.STROKE); 
    mPaint.setStrokeJoin(Paint.Join.MITER); 
    mPaint.setStrokeCap(Paint.Cap.ROUND); 
    mPaint.setStrokeWidth(12); 

    if (savedInstanceState != null) { 
     Log.d("TAG", "Restoring any bitmaps..."); 
     byte[] imageByteArray = (byte[]) savedInstanceState.getSerializable("ByteArray"); 
     BitmapFactory.Options opt = new BitmapFactory.Options(); 
     opt.inMutable = true; 
     Bitmap savedImage = BitmapFactory.decodeByteArray(imageByteArray, 0, imageByteArray.length, opt); 
     canvasView.mBitmap = savedImage; 
    } 
} 

在我的自定義視圖,MyView的,這裏就是我旋轉位圖的代碼的時候,屏幕的變化:

@Override 
protected void onSizeChanged(int w, int h, int oldw, int oldh) { 
    super.onSizeChanged(w, h, oldw, oldh); 
    Display display = ((WindowManager) getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay(); 
    int orientation = display.getRotation(); 
    Log.d("CANVAS", "Rotation: " + orientation); 
    if (mBitmap == null) { 
     mBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888); 
     mCanvas = new Canvas(mBitmap); 
    } else { 
     Matrix rotator = new Matrix(); 
     rotator.postRotate(orientation * 3); 
     Bitmap rotatedBitmap = Bitmap.createBitmap(mBitmap, 0, 0, mBitmap.getWidth(), mBitmap.getHeight(), rotator, true); 
     mCanvas = new Canvas(rotatedBitmap); 
     mCanvas.drawBitmap(rotatedBitmap, 0, 0, mPaint); 
    } 
} 

只是一切是一樣的,在Fingerpaint演示。我可以推下屏幕上的標記,但當我擡起手指時,我創建的路徑不會應用於位圖。

這裏的的onTouchEvent()的重複說明(我沒有修改):

public boolean onTouchEvent(MotionEvent event) { 
      float x = event.getX(); 
      float y = event.getY(); 
      switch (event.getAction()) { 
       case MotionEvent.ACTION_DOWN: 
        touch_start(x, y); 
        invalidate(); 
        break; 
       case MotionEvent.ACTION_MOVE: 
        touch_move(x, y); 
        invalidate(); 
        break; 
       case MotionEvent.ACTION_UP: 
        touch_up(); 
        invalidate(); 
        break; 
      } 
      return true; 
     } 

預先感謝任何見解。我懷疑我對Canvas應該如何工作的理解是不正確的,因此我的困惑!

[1]全Fingerpaint演示是在這裏:https://android.googlesource.com/platform/development/+/master/samples/ApiDemos/src/com/example/android/apis/graphics/FingerPaint.java

回答

1

BitmapFactory.decodeByteArray()忽略,你問一個可變位的選項,給你一個不可變因爲這是如何滾動。

https://developer.android.com/reference/android/graphics/BitmapFactory.html#decodeByteArray(byte[], int, int, android.graphics.BitmapFactory.Options)

decodeByteArray 
    Bitmap decodeByteArray (byte[] data, 
        int offset, 
        int length, 
        BitmapFactory.Options opts) 
    Decode an immutable bitmap from the specified byte array. 

你需要創建一個新的位圖對象,使用創建一個可變的位圖的方法之一。然後將不可變的位圖繪製成可變的位圖。然後扔你用那個函數加載的那個。

不可變性的原因是位圖是從你給它的那些字節創建的。所以對於速度他們是由這些字節支持。他們是相同的記憶。實際位圖對象的工作方式與此不同,並且您不能通過強制正常內存中的字節進入GPU來製作可變位圖。您可以製作第二個位圖對象並將數據繪製到第二個位圖中。

相關問題