如何打开图像并在其上绘图

2024-04-03

我正在创建一个应用程序,人们可以在其中绘制草图并保存到图库中。这我已经完成并且运行良好。我希望能够从画廊中获取一张图像并能够在其上进行绘制。我已经能够打开图库来选择图像,但我无法弄清楚如何将该图像嵌入到画布上然后进行绘制

但问题是,它打开了图库......但是当我单击任何图片打开时,它只是返回到应用程序,但不带图片,没有图片(我的屏幕保持与以前相同,没有新的图片)...那么问题出在哪里呢?

我的主要活动课---

package com.example.drawingfun;


import java.io.File;
import java.io.FileNotFoundException;
import java.io.InputStream;

import java.util.UUID;


import android.net.Uri;
import android.os.Bundle;
import android.provider.MediaStore;

import android.app.Activity;
import android.view.Menu;
import android.view.View;
import android.widget.ImageButton;

import android.widget.LinearLayout;
import android.widget.Toast;

import android.app.AlertDialog;
import android.app.Dialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.database.Cursor;


import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;


import android.view.View.OnClickListener;





public class MainActivity extends Activity implements OnClickListener {

    private DrawingView drawView;
    private ImageButton currPaint,drawBtn,eraseBtn, newBtn,saveBtn,gal;
    private float smallBrush, mediumBrush,largeBrush;

    int GALLERY_INTENT_CALLED = 3; // has to be a unique request code
    Drawable image;



    @Override
    protected void onCreate(Bundle savedInstanceState) {




        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        drawView = (DrawingView)findViewById(R.id.drawing);
        LinearLayout paintLayout = (LinearLayout)findViewById(R.id.paint_colors);
        currPaint = (ImageButton)paintLayout.getChildAt(0);
        currPaint.setImageDrawable(getResources().getDrawable(R.drawable.paint_pressed));
        smallBrush = getResources().getInteger(R.integer.small_size);
        mediumBrush = getResources().getInteger(R.integer.medium_size);
        largeBrush = getResources().getInteger(R.integer.large_size);




        drawBtn = (ImageButton)findViewById(R.id.draw_btn);
        drawBtn.setOnClickListener(this);


        drawView.setBrushSize(mediumBrush);
        eraseBtn = (ImageButton)findViewById(R.id.erase_btn);
        eraseBtn.setOnClickListener(this);
        newBtn = (ImageButton)findViewById(R.id.new_btn);
        newBtn.setOnClickListener(this);
        saveBtn = (ImageButton)findViewById(R.id.save_btn);
        saveBtn.setOnClickListener(this);
        gal = (ImageButton)findViewById(R.id.GalleryButton);
        gal.setOnClickListener(this);




    }



    public void paintClicked(View view){



        drawView.setErase(false);
        drawView.setBrushSize(drawView.getLastBrushSize());
        //use chosen color

        if(view!=currPaint){
            //update color
            ImageButton imgView = (ImageButton)view;
            String color = view.getTag().toString();
            drawView.setColor(color);
            imgView.setImageDrawable(getResources().getDrawable(R.drawable.paint_pressed));
            currPaint.setImageDrawable(getResources().getDrawable(R.drawable.paint));
            currPaint=(ImageButton)view;
            }







    }




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











    @Override
    public void onClick(View view){
        //respond to clicks
        if(view.getId()==R.id.draw_btn){
            //draw button clicked

            final Dialog brushDialog = new Dialog(this);
            brushDialog.setTitle("Brush size:");
            brushDialog.setContentView(R.layout.brush_chooser);


            ImageButton smallBtn = (ImageButton)brushDialog.findViewById(R.id.small_brush);
            smallBtn.setOnClickListener(new OnClickListener(){
                @Override
                public void onClick(View v) {
                    drawView.setErase(false);
                    drawView.setBrushSize(smallBrush);
                    drawView.setLastBrushSize(smallBrush);

                    brushDialog.dismiss();
                }
            });

            ImageButton mediumBtn = (ImageButton)brushDialog.findViewById(R.id.medium_brush);
            mediumBtn.setOnClickListener(new OnClickListener(){
                @Override
                public void onClick(View v) {
                    drawView.setErase(false);
                    drawView.setBrushSize(mediumBrush);
                    drawView.setLastBrushSize(mediumBrush);


                    brushDialog.dismiss();


                }
            });
            ImageButton largeBtn = (ImageButton)brushDialog.findViewById(R.id.large_brush);
            largeBtn.setOnClickListener(new OnClickListener(){
                @Override
                public void onClick(View v) {
                    drawView.setErase(false);
                    drawView.setBrushSize(largeBrush);
                    drawView.setLastBrushSize(largeBrush);

                    brushDialog.dismiss();
                }
            });






            brushDialog.show();






        }

























        else if(view.getId()==R.id.erase_btn){
            //switch to erase - choose size
            final Dialog brushDialog = new Dialog(this);
            brushDialog.setTitle("Eraser size:");
            brushDialog.setContentView(R.layout.brush_chooser);

            ImageButton smallBtn = (ImageButton)brushDialog.findViewById(R.id.small_brush);
            smallBtn.setOnClickListener(new OnClickListener(){
                @Override
                public void onClick(View v) {
                    drawView.setErase(true);
                    drawView.setBrushSize(smallBrush);
                    brushDialog.dismiss();
                }
            });
            ImageButton mediumBtn = (ImageButton)brushDialog.findViewById(R.id.medium_brush);
            mediumBtn.setOnClickListener(new OnClickListener(){
                @Override
                public void onClick(View v) {
                    drawView.setErase(true);
                    drawView.setBrushSize(mediumBrush);
                    brushDialog.dismiss();
                }
            });
            ImageButton largeBtn = (ImageButton)brushDialog.findViewById(R.id.large_brush);
            largeBtn.setOnClickListener(new OnClickListener(){
                @Override
                public void onClick(View v) {
                    drawView.setErase(true);
                    drawView.setBrushSize(largeBrush);
                    brushDialog.dismiss();
                }
            });
            brushDialog.show();
        }

        else if(view.getId()==R.id.new_btn){
            //new button

            AlertDialog.Builder newDialog = new AlertDialog.Builder(this);
            newDialog.setTitle("New drawing");
            newDialog.setMessage("Start new drawing (you will lose the current drawing)?");
            newDialog.setPositiveButton("Yes", new DialogInterface.OnClickListener(){
                public void onClick(DialogInterface dialog, int which){
                    drawView.startNew();
                    dialog.dismiss();
                }
            });
            newDialog.setNegativeButton("Cancel", new DialogInterface.OnClickListener(){
                public void onClick(DialogInterface dialog, int which){
                    dialog.cancel();
                }
            });
            newDialog.show();
        }


        else if(view.getId()==R.id.save_btn){
            //save drawing
            AlertDialog.Builder saveDialog = new AlertDialog.Builder(this);
            saveDialog.setTitle("Save drawing");
            saveDialog.setMessage("Save drawing to device Gallery?");
            saveDialog.setPositiveButton("Yes", new DialogInterface.OnClickListener(){
                public void onClick(DialogInterface dialog, int which){
                    //save drawing
                    drawView.setDrawingCacheEnabled(true);
                    //attempt to save
                    String imgSaved = MediaStore.Images.Media.insertImage(
                            getContentResolver(), drawView.getDrawingCache(),
                            UUID.randomUUID().toString()+".png", "drawing");
                    //feedback
                    if(imgSaved!=null){
                        Toast savedToast = Toast.makeText(getApplicationContext(), 
                                "Drawing saved to Gallery!", Toast.LENGTH_SHORT);
                        savedToast.show();
                    }
                    else{
                        Toast unsavedToast = Toast.makeText(getApplicationContext(), 
                                "Oops! Image could not be saved.", Toast.LENGTH_SHORT);
                        unsavedToast.show();
                    }
                    drawView.destroyDrawingCache();
                }
            });
            saveDialog.setNegativeButton("Cancel", new DialogInterface.OnClickListener(){
                public void onClick(DialogInterface dialog, int which){
                    dialog.cancel();
                }
            });
            saveDialog.show();
        }










        else if(view.getId()==R.id.GalleryButton){
            //new button
            AlertDialog.Builder newDialog = new AlertDialog.Builder(this);
            newDialog.setTitle("New drawing");
            newDialog.setMessage("Start new drawing (you will lose the current drawing)?");
            newDialog.setPositiveButton("Yes", new DialogInterface.OnClickListener(){
                public void onClick(DialogInterface dialog, int which){
                    Intent choosePictureIntent = new Intent(
                            Intent.ACTION_PICK,
                            android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
                    startActivityForResult(choosePictureIntent, 101);


                }

            });
            newDialog.setNegativeButton("Cancel", new DialogInterface.OnClickListener(){
                public void onClick(DialogInterface dialog, int which){
                    dialog.cancel();
                }
            });
            newDialog.show();
        }


    }
















    public void  setDrawingThemefrmGallery()
    {

        Intent pickPhoto = new Intent(
                Intent.ACTION_PICK,
                android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
            startActivityForResult(pickPhoto, GALLERY_INTENT_CALLED);

    }

    public static Bitmap drawableToBitmap (Drawable drawable) {
        if (drawable instanceof BitmapDrawable) {
            return ((BitmapDrawable)drawable).getBitmap();
        }

        Bitmap bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), Config.ARGB_8888);
        Canvas canvas = new Canvas(bitmap); 
        drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
        drawable.draw(canvas);

        return bitmap;
    }



    protected void onActivityResult(int requestCode, int resultCode,
            Intent returnedIntent) {
        drawView.drawImage(drawableToBitmap(image));
        super.onActivityResult(requestCode, resultCode, returnedIntent);
    if (requestCode ==  GALLERY_INTENT_CALLED) {
        if (resultCode == RESULT_OK) {
            try {
                Uri selectedImage = returnedIntent.getData();
                InputStream inputStream = getContentResolver().openInputStream(selectedImage);
                image = Drawable.createFromStream(inputStream, selectedImage.toString());
            } catch (FileNotFoundException e) {}
        }
    }
}













}

我的DrawingView类---

package com.example.drawingfun;

import java.io.File;

import android.view.View;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.net.Uri;
import android.provider.MediaStore;
import android.util.AttributeSet;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.BitmapFactory;
import android.graphics.BitmapShader;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.CornerPathEffect;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Shader;
import android.view.MotionEvent;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.util.TypedValue;



public class DrawingView extends View {

    //drawing path
    private Path drawPath;
    //drawing and canvas paint
    private Paint drawPaint, canvasPaint;
    //initial color
    private int paintColor = 0xFF660000;
    //canvas
    private Canvas drawCanvas;
    //canvas bitmap
    private Bitmap canvasBitmap;
    private float brushSize, lastBrushSize;
    private boolean erase=false;



    public DrawingView(Context context, AttributeSet attrs) {
        super(context, attrs);
        setupDrawing();
        // TODO Auto-generated constructor stub
    }

    private void setupDrawing() {
        // TODO Auto-generated method stub



        brushSize = getResources().getInteger(R.integer.medium_size);
        lastBrushSize = brushSize;



        drawPath = new Path();
        drawPaint = new Paint();
        drawPaint.setColor(paintColor);

        drawPaint.setAntiAlias(true);
        drawPaint.setStrokeWidth(brushSize);
        drawPaint.setStyle(Paint.Style.FILL_AND_STROKE);
        drawPaint.setStrokeJoin(Paint.Join.ROUND);
        drawPaint.setStrokeCap(Paint.Cap.ROUND);


        canvasPaint = new Paint(Paint.DITHER_FLAG);




    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        //view given size
        super.onSizeChanged(w, h, oldw, oldh);
        canvasBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
        drawCanvas = new Canvas(canvasBitmap);
        }

    @Override
    protected void onDraw(Canvas canvas) {
    //draw view
        canvas.drawBitmap(canvasBitmap, 0, 0, canvasPaint);
        canvas.drawPath(drawPath, drawPaint);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
    //detect user touch
        float touchX = event.getX();
        float touchY = event.getY();
        switch (event.getAction()) {
        case MotionEvent.ACTION_DOWN:
            drawPath.moveTo(touchX, touchY);
            break;
        case MotionEvent.ACTION_MOVE:
            drawPath.lineTo(touchX, touchY);
            break;
        case MotionEvent.ACTION_UP:
            drawPath.lineTo(touchX, touchY);
            drawCanvas.drawPath(drawPath, drawPaint);
            drawPath.reset();
            break;
        default:
            return false;
        }
        invalidate();
        return true;
    }

    public void setColor(String newColor){
        //set color
        invalidate();
        if(newColor.startsWith("#")){
            paintColor = Color.parseColor(newColor);
            drawPaint.setColor(paintColor);
            drawPaint.setShader(null);
        }
        else{
            //pattern
            int patternID = getResources().getIdentifier(
                    newColor, "drawable", "com.example.drawingfun");
            //decode 
            Bitmap patternBMP = BitmapFactory.decodeResource(getResources(), patternID);
            //create shader
            BitmapShader patternBMPshader = new BitmapShader(patternBMP, 
                    Shader.TileMode.REPEAT, Shader.TileMode.REPEAT);  
            //color and shader
            drawPaint.setColor(0xFFFFFFFF);
            drawPaint.setShader(patternBMPshader);
        }
        }

    public void setBrushSize(float newSize){
        //update size
        float pixelAmount = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
                newSize, getResources().getDisplayMetrics());
            brushSize=pixelAmount;
            drawPaint.setStrokeWidth(brushSize);
        }

    public void setLastBrushSize(float lastSize){
        lastBrushSize=lastSize;
    }
    public float getLastBrushSize(){
        return lastBrushSize;
    }


    public void setErase(boolean isErase){
        //set erase true or false
        erase=isErase;

        if(erase) 
        {


            paintColor = Color.parseColor("WHITE");
            drawPaint.setColor(paintColor);
            //drawPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
            drawPaint.setShader(null);





        }

        else 


            drawPaint.setXfermode(null);

        }

    public void startNew(){
        drawCanvas.drawColor(0, PorterDuff.Mode.CLEAR);
        invalidate();
    }





    public void drawImage(Bitmap image) {
        drawCanvas.drawBitmap(image, 0, 0, canvasPaint);
        invalidate();
    }















    }

您需要将图像加载为位图,然后使用 Canvas 对象绘制它们。

参考这个问题 https://stackoverflow.com/questions/3035692/how-to-convert-a-drawable-to-a-bitmap了解如何将可绘制对象转换为位图。

并按照这个例子:

public class DrawView extends View{

    private Paint bufferPaint;
    private Bitmap buffer;
    private Canvas board;
    private Path currPath;

    public DrawView(Context context) {
        super(context);
        bufferPaint = new Paint(Paint.DITHER_FLAG);
    }

    public void init() {
        buffer = Bitmap.createBitmap(getWidth(), getHeight(),
                Bitmap.Config.ARGB_8888);
        board = new Canvas(buffer);
        invalidate();
    }

    public void drawBitmap(Bitmap bitmap) {
        board.drawBitmap(bitmap, 0, 0, bufferPaint)
    }

    @Override
    public void onDraw(Canvas canvas) {
        if (buffer != null) {
            canvas.drawBitmap(buffer, 0, 0, bufferPaint);
        }
    }
}

drawBitmap 方法可以解决这个问题。现在您可以使用画布对象(板)在位图上绘制其他内容。

全局定义这些

int GALLERY_INTENT_CALLED = 3; // has to be a unique request code
Drawable image;

使用此代码从用户处获取图像

Intent pickPhoto = new Intent(
                Intent.ACTION_PICK,
                android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(pickPhoto, GALLERY_INTENT_CALLED);

然后在您的活动的 onActivityResult 中获取图像

protected void onActivityResult(int requestCode, int resultCode,
            Intent returnedIntent) {
        super.onActivityResult(requestCode, resultCode, returnedIntent);
    if (requestCode ==  CAMERA_INTENT_CALLED) {
        if (resultCode == RESULT_OK) {
            try {
                Uri selectedImage = returnedIntent.getData()
                InputStream inputStream = getContentResolver().openInputStream(selectedImage);
                image = Drawable.createFromStream(inputStream, selectedImage.toString());
            } catch (FileNotFoundException e) {}
        }
    }
}

在DrawingView中写这个方法

public void drawImage(Bitmap image) {
    drawCanvas.drawBitmap(image, 0, 0, canvasPaint);
    invalidate();
}

使用这篇文章中的方法将图像转换为位图:

public static Bitmap drawableToBitmap (Drawable drawable) {
    if (drawable instanceof BitmapDrawable) {
        return ((BitmapDrawable)drawable).getBitmap();
    }

    Bitmap bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), Config.ARGB_8888);
    Canvas canvas = new Canvas(bitmap); 
    drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
    drawable.draw(canvas);

    return bitmap;
}

然后每当在 Mainactivity 中你想绘制图像调用

drawView.drawImage(drawableToBitmap(image))
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何打开图像并在其上绘图 的相关文章

随机推荐

  • 正则表达式在字符串中查找数字

    我有一个字符串 可能包含也可能不包含 4 或 5 位数字 我正在寻找一个正则表达式 可以检测字符串是否确实有这样的数字 避免较长数字的万无一失的方法是 d d 4 5 d 我假设您不想在千位数字后面留有逗号 如果你这样做的话 d d 1 2
  • Symfony - 以生成的形式添加文本

    我想做一些非常简单的事情 但我不知道如何管理它 我有一个表格 form start form form widget form form end form 其中有几个文本字段 我想 插入 一些文本 例如 p my Text p 在两个文本字
  • lex :如何覆盖 YY_BUF_SIZE

    根据manual http westes github io flex manual The Default Memory Management html YY BUF SIZE is 16K我们需要重写它 但是 手册没有指定如何覆盖它 我
  • Tar:创建除一个之外的存档排除目录

    我有一些目录和一些文件 dir archive somedir1 dir archive somedir2 dir archive somedir3 dir archive mydir dir archive mydir excludedi
  • 在控制台中检测 Ctrl + S

    I m developing a console application in which I need to detect several hotkeys such as Ctrl N Ctrl O and Ctrl S Here s a
  • 如何在Excel中无法以图形方式显示的外部数据查询中添加参数?

    我经常使用 MS ExcelGet External Data创建简单的报告 对数据库运行查询并在 Excel 中很好地显示 Excel 的强大功能 例如过滤和数据透视表 以及用户熟悉的界面使其非常适合此目的 但是 Microsoft Qu
  • 如何反转 go 中的切片?

    如何反转任意切片 interface 在 Go 中 我宁愿不必写Less and Swap to use sort Reverse 有没有一种简单的内置方法可以做到这一点 Use 切片 反转 https pkg go dev slices
  • 错误:我们没有使用 Azure CLI 的有效访问权限

    我是 Azure CLI 的新用户 所以 我昨天开始使用它 一切正常 直到我在控制台上收到一条消息 要求我使用 Azure 登录命令再次登录 我按照消息所说的做了 打开我的浏览器并输入代码 浏览器加载页面 一切正常 但是 当我进入控制台窗口
  • 如何在 Maven 中创建校验和然后将其输出到文本文件?

    还在学习如何使用Maven 我想知道是否有办法做到checksum在生成的WAR file The Maven目标是package 我想要实现的是得到一个checksum价值 包装的WAR文件 与打包文件一起放入文本文件中 提前致谢 让它与
  • 当我移动轨迹栏时,如何防止 Windows 通用控件 6.0 中的控件(选项卡)闪烁和消失?

    滑动滑动条并释放鼠标按钮时 整个窗口都会闪烁 并且选项卡会消失 当我使用旧版本时 一切正常 当我使用新的 Microsoft Windows Common Controls ver 6 0 时 出现此问题 include
  • Flink 检查点到 Google Cloud Storage

    我正在尝试为 GCS 中的 flink 作业配置检查点 如果我在本地运行测试作业 没有 docker 和任何集群设置 一切正常 但如果我使用 docker compose 或集群设置运行它并在 flink 仪表板中使用作业部署 fat ja
  • Android 中的文本转语音完成后立即播放音频文件

    我正在尝试开发一个 Android 应用程序 一旦文本到语音完成 就必须播放音频文件 这个怎么做 如果我没有理解错的话 您想使用文本转语音来读取一些文本 同时将语音音频存储到手机中 然后再播放音频 你检查过吗录音测试 http develo
  • Mesos 任务 - 无法接受套接字:未来已丢弃

    我只是想将 mesos 版本从 1 0 3 升级到 1 3 1 Chronos 调度程序能够通过 mesos 调度作业 该作业运行良好并且能够查看 mesos 标准输出日志 但是 仍然在 mesos stderr 日志中看到以下内容 doc
  • 使用 MySQL 进行 SVN 身份验证

    我正在尝试通过 MySQL 设置每个存储库 SVN 身份验证 但遇到一些问题 首先 两者有什么区别mod authn dbd and mod auth mysql 其次 我已经有一个 MySQL 数据库设置 其中包含用户 组和权限的表 是否
  • 如何从 Amplify 生成的 Lambda 函数中访问其他 AWS 资源?

    我一直在使用 AWS Amplify 作为 AWS 的新手 我非常喜欢 Amplify 如何在 AWS 上为我配置必要的资源和 IAM 角色 我的问题是关于将 Lambda 与 GraphQL 结合使用 按照文档 我可以创建一个自定义 Gr
  • 可以使用反射覆盖 IEnumerable 中的项目吗?

    不顾任何合理的理由这样做 只是出于好奇是否可以获取任何给定的 IEnumerable T 并覆盖其中包含的项目 例如 给定 IEnuemrable String 是否可以完全替换 IEnumerable 中的所有字符串 正如其他人所说 如果
  • 背景尺寸:包含

    我想要一个带有背景图像的 div 保持图像的纵横比 固定高度为 500px 并且我不希望该 div 的背景上有 填充 这可以吗 我可以获得一个具有固定高度和保持宽高比的背景图像的 div div style background url s
  • 如何使用 Google 字体更改 Bootstrap 默认字体系列?

    我正在创建一个博客网站 我想更改 Bootstrap 字体 在 header 中的 import CSS 中我添加了这个字体 如何使用它作为我的引导程序默认字体 首先 你不能通过这种方式将字体导入到 CSS 中 您可以在 HTML 头中添加
  • Swift 中的元组是否可以完全替代 C# 中的匿名类型

    Like C 中的匿名类型 http msdn microsoft com en us library bb397696 aspx 新推出的语言 Swift 中的元组可以做 C 中的匿名类型可以做的事情吗 在学习 swift 时 我发现了一
  • 如何打开图像并在其上绘图

    我正在创建一个应用程序 人们可以在其中绘制草图并保存到图库中 这我已经完成并且运行良好 我希望能够从画廊中获取一张图像并能够在其上进行绘制 我已经能够打开图库来选择图像 但我无法弄清楚如何将该图像嵌入到画布上然后进行绘制 但问题是 它打开了