2013-09-07 105 views
10

tôi cố gắng sử dụng các mã sau đây đểỨng dụng Android - Cách lưu bản vẽ bitmap trên canvas dưới dạng hình ảnh? Kiểm tra mã?

  1. Draw trên vải
  2. Save the canvas trên ảnh

Vấn đề - Khi tôi cố gắng để lưu các hình ảnh, nó cho thấy một lỗi con trỏ null và không có gì được lưu.

Vui lòng giúp tôi tìm sự cố với mã hoặc đề xuất cho tôi một mã thay thế, điều này hoàn toàn giống nhau. Cảm ơn trước.

Mã để vẽ trên vải:

package com.example.draw2; 

import android.content.Context; 
import android.graphics.Bitmap; 
import android.graphics.Canvas; 
import android.graphics.Color; 
import android.graphics.Paint; 
import android.graphics.Path; 
import android.util.AttributeSet; 
import android.view.MotionEvent; 
import android.view.View; 

public class MyDrawView extends View { 
    private Bitmap mBitmap; 
    private Canvas mCanvas; 
    private Path mPath; 
    private Paint mBitmapPaint; 
    private Paint mPaint; 

    public MyDrawView(Context c, AttributeSet attrs) { 
     super(c, attrs); 

     mPath = new Path(); 
     mBitmapPaint = new Paint(Paint.DITHER_FLAG); 

     mPaint = new Paint(); 
     mPaint.setAntiAlias(true); 
     mPaint.setDither(true); 
     mPaint.setColor(0xFF000000); 
     mPaint.setStyle(Paint.Style.STROKE); 
     mPaint.setStrokeJoin(Paint.Join.ROUND); 
     mPaint.setStrokeCap(Paint.Cap.ROUND); 
     mPaint.setStrokeWidth(9); 
    } 


    @Override 
    protected void onSizeChanged(int w, int h, int oldw, int oldh) { 
     super.onSizeChanged(w, h, oldw, oldh); 
     mBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888); 
     mCanvas = new Canvas(mBitmap); 
    } 

    @Override 
    protected void onDraw(Canvas canvas) { 
     canvas.drawBitmap(mBitmap, 0, 0, mBitmapPaint); 

     canvas.drawPath(mPath, mPaint); 


    } 

    private float mX, mY; 
    private static final float TOUCH_TOLERANCE = 4; 

    private void touch_start(float x, float y) { 
     mPath.reset(); 
     mPath.moveTo(x, y); 
     mX = x; 
     mY = y; 
    } 
    private void touch_move(float x, float y) { 
     float dx = Math.abs(x - mX); 
     float dy = Math.abs(y - mY); 
     if (dx >= TOUCH_TOLERANCE || dy >= TOUCH_TOLERANCE) { 
      mPath.quadTo(mX, mY, (x + mX)/2, (y + mY)/2); 
      mX = x; 
      mY = y; 
     } 
    } 
    private void touch_up() { 
     mPath.lineTo(mX, mY); 
     // commit the path to our offscreen 
     mCanvas.drawPath(mPath, mPaint); 
     // kill this so we don't double draw 
     mPath.reset(); 
    } 

    @Override 
    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; 
    } 

    public Bitmap getBitmap() 
    { 
    return mBitmap; 
    } 



    public void clear(){ 
     mBitmap.eraseColor(Color.GREEN); 
     invalidate(); 
     System.gc(); 

    } 

} 

mã thứ hai để tiết kiệm vải như hình ảnh trong hoạt động chính.

Tôi đã thử một vài điều và một số phần của mã được nhận xét.

Kể từ khi tôi là một người mới bắt đầu, tôi đánh giá cao bất kỳ lời khuyên

mã thứ hai MainActivity:

package com.example.draw2; 

import java.io.File; 
import java.io.FileNotFoundException; 
import java.io.FileOutputStream; 
import java.io.IOException; 

import android.app.Activity; 
import android.graphics.Bitmap; 
import android.os.Bundle; 
import android.os.Environment; 
import android.view.Menu; 
import android.view.View; 
import android.widget.Button; 
import android.widget.Toast; 


public class MainActivity extends Activity 
{ 
    MyDrawView myDrawView; 


    @Override 
    protected void onCreate(Bundle savedInstanceState) 
    { 

     super.onCreate(savedInstanceState); 
     myDrawView = new MyDrawView(this, null); 
     setContentView(R.layout.activity_main); 

     Button button1 = (Button)findViewById(R.id.button1);  
     button1.setOnClickListener(new View.OnClickListener() 
     { 
      public void onClick(View v) 
      {  
       //View content = myDrawView; 

       //System.out.println(content); 


       //Bitmap bitmap = content.getDrawingCache(); 

       File folder = new File(Environment.getExternalStorageDirectory().toString()); 
       boolean success = false; 
       if (!folder.exists()) 
       { 
        success = folder.mkdirs(); 
       } 

       System.out.println(success+"folder"); 

       File file = new File(Environment.getExternalStorageDirectory().toString() + "/sample.JPEG"); 

      if (!file.exists()) 
      { 
        try { 
        success = file.createNewFile(); 
       } catch (IOException e) { 
        e.printStackTrace(); 
       } 
      } 

      System.out.println(success+"file"); 



      FileOutputStream ostream = null; 
       try 
       { 
       ostream = new FileOutputStream(file); 

       System.out.println(ostream); 

       Bitmap save = myDrawView.getBitmap(); 
       if(save == null) { 
        System.out.println("NULL bitmap save\n"); 
       } 
       save.compress(Bitmap.CompressFormat.PNG, 100, ostream); 
       //bitmap.compress(Bitmap.CompressFormat.PNG, 100, ostream); 
        ostream.flush(); 
        ostream.close(); 
       }catch (NullPointerException e) 
       { 
        e.printStackTrace(); 
        Toast.makeText(getApplicationContext(), "Null error", Toast.LENGTH_SHORT).show(); 
       } 

       catch (FileNotFoundException e) 
       { 
        e.printStackTrace(); 
        Toast.makeText(getApplicationContext(), "File error", Toast.LENGTH_SHORT).show(); 
       } 

       catch (IOException e) 
       { 
        e.printStackTrace(); 
        Toast.makeText(getApplicationContext(), "IO error", Toast.LENGTH_SHORT).show(); 
       } 

      } 
     }); 

    } 


    @Override 
    public boolean onCreateOptionsMenu(Menu menu) { 
     // Inflate the menu; this adds items to the action bar if it is present. 
     getMenuInflater().inflate(R.menu.main, menu); 
     return true; 
    } 
} 
+0

Tôi không thể tìm thấy mã lấy hình ảnh để lưu nó ở bất kỳ đâu trong sự kiện nhấp chuột của bạn! bạn đã tạo một tệp trống và sau đó cố gắng đọc tệp trống đó. Ý bạn là bạn muốn chúng tôi cung cấp cho bạn những dòng mã này? – hasan83

+0

Tôi quan tâm để biết những sai lầm trong mã này, và làm thế nào tôi có thể cải thiện nó. – prateek

+0

Tôi đã thử câu trả lời của JRowan ở đây và nó đã làm việc cho tôi. Bạn đang nói rằng nó không làm việc cho bạn? – hasan83

Trả lời

19

MyDrawView

import android.annotation.SuppressLint; 
import android.content.Context; 
import android.graphics.Bitmap; 
import android.graphics.Bitmap.Config; 
import android.graphics.Canvas; 
import android.graphics.Color; 
import android.graphics.Paint; 
import android.graphics.Path; 
import android.graphics.Rect; 
import android.util.AttributeSet; 
import android.util.LruCache; 
import android.view.MotionEvent; 
import android.view.View; 

public class MyDrawView extends View { 
    public Bitmap mBitmap; 
    public Canvas mCanvas; 
    private Path mPath; 
    private Paint mBitmapPaint; 
    private Paint mPaint; 


    public MyDrawView(Context c, AttributeSet attrs) { 
     super(c, attrs); 

     mPath = new Path(); 
     mBitmapPaint = new Paint(Paint.DITHER_FLAG); 

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

    } 


    @Override 
    protected void onSizeChanged(int w, int h, int oldw, int oldh) { 
     super.onSizeChanged(w, h, oldw, oldh); 
     mBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888); 
     mCanvas = new Canvas(mBitmap); 
    } 

    @Override 
    protected void onDraw(Canvas canvas) { 
     canvas.drawBitmap(mBitmap, 0, 0, mBitmapPaint); 

     canvas.drawPath(mPath, mPaint); 


    } 

    private float mX, mY; 
    private static final float TOUCH_TOLERANCE = 4; 

    private void touch_start(float x, float y) { 
     mPath.reset(); 
     mPath.moveTo(x, y); 
     mX = x; 
     mY = y; 
    } 
    private void touch_move(float x, float y) { 
     float dx = Math.abs(x - mX); 
     float dy = Math.abs(y - mY); 
     if (dx >= TOUCH_TOLERANCE || dy >= TOUCH_TOLERANCE) { 
      mPath.quadTo(mX, mY, (x + mX)/2, (y + mY)/2); 
      mX = x; 
      mY = y; 
     } 
    } 
    private void touch_up() { 
     mPath.lineTo(mX, mY); 
     // commit the path to our offscreen 
     mCanvas.drawPath(mPath, mPaint); 
     // kill this so we don't double draw 
     mPath.reset(); 
    } 

    @Override 
    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; 
    } 

    public Bitmap getBitmap() 
    { 
     //this.measure(100, 100); 
     //this.layout(0, 0, 100, 100); 
     this.setDrawingCacheEnabled(true); 
     this.buildDrawingCache(); 
     Bitmap bmp = Bitmap.createBitmap(this.getDrawingCache()); 
     this.setDrawingCacheEnabled(false); 


    return bmp; 
    } 



    public void clear(){ 
     mBitmap.eraseColor(Color.GREEN); 
     invalidate(); 
     System.gc(); 

    } 

} 

MainActivity

import java.io.File; 
import java.io.FileNotFoundException; 
import java.io.FileOutputStream; 
import java.io.IOException; 

import android.app.Activity; 
import android.graphics.Bitmap; 
import android.graphics.Bitmap.Config; 
import android.graphics.Canvas; 
import android.graphics.Color; 
import android.graphics.Paint; 
import android.graphics.Rect; 
import android.graphics.drawable.BitmapDrawable; 
import android.os.Bundle; 
import android.os.Environment; 
import android.view.Menu; 
import android.view.View; 
import android.view.View.MeasureSpec; 
import android.widget.Button; 
import android.widget.Toast; 


public class MainActivity extends Activity 
{ 
    MyDrawView myDrawView; 


    @Override 
    protected void onCreate(Bundle savedInstanceState) 
    { 

     super.onCreate(savedInstanceState); 
     // myDrawView = new MyDrawView(this, null); 
     setContentView(R.layout.activity_main); 
     myDrawView = (MyDrawView)findViewById(R.id.draw); 
     Button button1 = (Button)findViewById(R.id.button1);  
     button1.setOnClickListener(new View.OnClickListener() 
     { 
      public void onClick(View v) 
      {  


       File folder = new File(Environment.getExternalStorageDirectory().toString()); 
       boolean success = false; 
       if (!folder.exists()) 
       { 
        success = folder.mkdirs(); 
       } 

       System.out.println(success+"folder"); 

       File file = new File(Environment.getExternalStorageDirectory().toString() + "/sample.png"); 

      if (!file.exists()) 
      { 
        try { 
        success = file.createNewFile(); 
       } catch (IOException e) { 
        e.printStackTrace(); 
       } 
      } 

      System.out.println(success+"file"); 



      FileOutputStream ostream = null; 
       try 
       { 
       ostream = new FileOutputStream(file); 

       System.out.println(ostream); 
       View targetView = myDrawView; 

       // myDrawView.setDrawingCacheEnabled(true); 
       // Bitmap save = Bitmap.createBitmap(myDrawView.getDrawingCache()); 
       // myDrawView.setDrawingCacheEnabled(false); 
       // copy this bitmap otherwise distroying the cache will destroy 
       // the bitmap for the referencing drawable and you'll not 
       // get the captured view 
       // Bitmap save = b1.copy(Bitmap.Config.ARGB_8888, false); 
       //BitmapDrawable d = new BitmapDrawable(b); 
       //canvasView.setBackgroundDrawable(d); 
       // myDrawView.destroyDrawingCache(); 
       // Bitmap save = myDrawView.getBitmapFromMemCache("0"); 
       // myDrawView.setDrawingCacheEnabled(true); 
       //Bitmap save = myDrawView.getDrawingCache(false); 
       Bitmap well = myDrawView.getBitmap(); 
       Bitmap save = Bitmap.createBitmap(320, 480, Config.ARGB_8888); 
       Paint paint = new Paint(); 
       paint.setColor(Color.WHITE); 
       Canvas now = new Canvas(save); 
       now.drawRect(new Rect(0,0,320,480), paint); 
       now.drawBitmap(well, new Rect(0,0,well.getWidth(),well.getHeight()), new Rect(0,0,320,480), null); 

       // Canvas now = new Canvas(save); 
       //myDrawView.layout(0, 0, 100, 100); 
       //myDrawView.draw(now); 
       if(save == null) { 
        System.out.println("NULL bitmap save\n"); 
       } 
       save.compress(Bitmap.CompressFormat.PNG, 100, ostream); 
       //bitmap.compress(Bitmap.CompressFormat.PNG, 100, ostream); 
        //ostream.flush(); 
        //ostream.close(); 
       }catch (NullPointerException e) 
       { 
        e.printStackTrace(); 
        Toast.makeText(getApplicationContext(), "Null error", Toast.LENGTH_SHORT).show(); 
       } 

       catch (FileNotFoundException e) 
       { 
        e.printStackTrace(); 
        Toast.makeText(getApplicationContext(), "File error", Toast.LENGTH_SHORT).show(); 
       } 

       catch (IOException e) 
       { 
        e.printStackTrace(); 
        Toast.makeText(getApplicationContext(), "IO error", Toast.LENGTH_SHORT).show(); 
       } 

      } 
     }); 

    } 


    @Override 
    public boolean onCreateOptionsMenu(Menu menu) { 
     // Inflate the menu; this adds items to the action bar if it is present. 
     getMenuInflater().inflate(R.menu.main, menu); 
     return true; 
    } 
} 

activity_m ain.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    xmlns:tools="http://schemas.android.com/tools" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:paddingBottom="@dimen/activity_vertical_margin" 
    android:paddingLeft="@dimen/activity_horizontal_margin" 
    android:paddingRight="@dimen/activity_horizontal_margin" 
    android:paddingTop="@dimen/activity_vertical_margin" 
    tools:context=".MainActivity" > 
<com.example.draw2.MyDrawView 
    android:id ="@+id/draw" 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content"></com.example.draw2.MyDrawView>" 
    <Button 
     android:id ="@+id/button1" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:text="save" 
     android:layout_alignParentBottom="true" 
     ></Button>" 

</RelativeLayout> 

và trong AndroidManifest.xml của bạn chắc chắn rằng bạn có

<?xml version="1.0" encoding="utf-8"?> 
<manifest xmlns:android="http://schemas.android.com/apk/res/android" 
    package="com.example.draw2" 
    android:versionCode="1" 
    android:versionName="1.0" > 

    <uses-sdk 
     android:minSdkVersion="8" 
     android:targetSdkVersion="17" /> 
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/> 
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> 

    <application 
     android:allowBackup="true" 
     android:icon="@drawable/ic_launcher" 
     android:label="@string/app_name" 
     android:theme="@style/AppTheme" > 
     <activity 
      android:name="com.example.draw2.MainActivity" 
      android:label="@string/app_name" > 
      <intent-filter> 
       <action android:name="android.intent.action.MAIN" /> 

       <category android:name="android.intent.category.LAUNCHER" /> 
      </intent-filter> 
     </activity> 
    </application> 

</manifest> 
+0

Cảm ơn bạn đã phản hồi nhanh , hãy để tôi thử điều này nếu nó hoạt động !! – prateek

+0

Tôi đã thử đề xuất của bạn nhưng nó không giải quyết được vấn đề? – prateek

+0

bạn có thể đặt logcat để tôi có thể xem chi tiết về sự cố không? – JRowan

0

Có một chút thêm vào trong đoạn code trên. Đoạn mã trên là lưu pic vào bộ nhớ. Nhưng hình ảnh không hiển thị trong thư viện. Để hiển thị hình ảnh trong bộ sưu tập chỉ cần thiết lập một MediaScannerConnection cho bitmap chúng tôi đang tiết kiệm

Chức năng Sample

public void scanPhoto(final String imageFileName) { 
    MediaScannerConnection msConn = new MediaScannerConnection(PaintPic.this, 
      new MediaScannerConnectionClient() { 
       public void onMediaScannerConnected() { 
        msConn.scanFile(imageFileName, null); 
        Log.i("msClient obj in Photo Utility", 
          "connection established"); 
       } 

       public void onScanCompleted(String path, Uri uri) { 
        msConn.disconnect(); 
        Log.i("msClient obj in Photo Utility", "scan completed"); 
       } 
      }); 
    msConn.connect(); 
} 

gọi chức năng này ngay sau khi dòng này

save.compress(Bitmap.CompressFormat.PNG, 100, ostream); 

Bây giờ bitmap đã lưu cũng hiển thị trong Gallery