Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/180.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Android应用程序-如何将画布上的位图图形保存为图像?检查代码?_Java_Android_Bitmap_Android Canvas - Fatal编程技术网

Java Android应用程序-如何将画布上的位图图形保存为图像?检查代码?

Java Android应用程序-如何将画布上的位图图形保存为图像?检查代码?,java,android,bitmap,android-canvas,Java,Android,Bitmap,Android Canvas,我尝试使用以下代码 在画布上画画 将画布保存在图像上 问题-当我试图保存图像时,它显示一个空指针错误,并且没有保存任何内容 请帮我找到代码的问题,或者给我建议一个替代方案,当然也一样。提前谢谢 要在画布上绘制的代码: package com.example.draw2; import android.content.Context; import android.graphics.Bitmap; import android.graphics.Canvas; import android.gr

我尝试使用以下代码

  • 在画布上画画
  • 将画布保存在图像上
  • 问题-当我试图保存图像时,它显示一个空指针错误,并且没有保存任何内容

    请帮我找到代码的问题,或者给我建议一个替代方案,当然也一样。提前谢谢

    要在画布上绘制的代码:

    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();
    
        }
    
    }
    
    将画布另存为图像的第二个代码位于主活动中

    我尝试了一些方法,并对部分代码进行了注释

    因为我是一个初学者,所以我很感激任何建议

    第二个代码活动:

    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;
        }
    }
    
    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();
    
        }
    
    }
    
    主要活动

    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_main.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>
    
    
    "
    "
    
    在AndroidManifest.xml中,确保

     <?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>
    

    上述代码中有一个小的附加项。上述代码将pic保存在存储器中。但这张照片没有在画廊中展出。要在gallery中显示图像,只需为正在保存的位图设置一个
    MediaScannerConnection

    示例函数

    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();
    }
    
    并在该行之后调用该函数

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

    现在保存的位图也可以在
    图库中看到

    我在点击事件中找不到将图像保存到任何位置的代码!您创建了一个空文件,然后试图读取该空文件。你的意思是你想让我们为你提供这些代码行吗?我很想知道这些代码中的错误,以及如何改进它。我在这里尝试了JRowan的答案,它对我有效。你是说它不适合你吗?你的代码不画图!它绘制,我在三星galaxy ace上安装了上述程序,我能够绘制,但在保存的同时仍然显示空错误。你能打开logcat让我看到崩溃的细节吗?它不会崩溃,当我在应用程序上绘制一些东西并试图保存时,它显示空。我已经采纳了你的建议,请检查它是否工作。我刚进去,抱歉耽搁了,给我一点时间。我将在我的IDE中复制你的代码,并让你知道问题出在哪里。很快我就注意到了一些问题,我刚刚做了一个更改