Android:如何:在静态图像(png文件)中绘制形状和文本,然后放入ImageView中?

发布于 2024-12-03 06:07:31 字数 6288 浏览 2 评论 0原文

这是我当前的代码:

public class MallMapActivity extends Activity {
    private final static String tag = "MallMapActivity";
    private ImageView iv;
    private final static String FLOOR = "F";
    private final String storagePath = Environment.getExternalStorageDirectory() + "/appdata23";
    private final String localMapsPath = storagePath + "/localMaps";

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        iv = (ImageView)findViewById(R.id.imageview);
        //iv.setScaleType(ScaleType.FIT_XY);

        final LinearLayout levelLayout = (LinearLayout) findViewById(R.id.level_layout);
        int levelSize = 8;
        for (int i = 0; i < levelSize; i++) {
            Button levelButton = new Button(this.getApplicationContext());
            if(i==0) {
                levelButton.setText(new StringBuffer((i+1)+"").append(FLOOR).append("(start)"));
            } else if (i==7) {
                levelButton.setText(new StringBuffer((i+1)+"").append(FLOOR).append("(end)"));
            } else {
                levelButton.setText(new StringBuffer((i+1)+"").append(FLOOR));
            }
            levelButton.setTag((i+1) + FLOOR);
            levelButton.setId(i);
            levelButton.setLayoutParams(
                    new RadioGroup.LayoutParams(0, RadioGroup.LayoutParams.WRAP_CONTENT, 1));
            levelButton.setOnClickListener(new OnClickListener() {

                @Override
                public void onClick(View view) {
                    int childCount = levelLayout.getChildCount();
                    int viewId = view.getId();

                    for (int j = 0; j < childCount; j++) {
                        Button btn = (Button)levelLayout.getChildAt(j); 
                        if(viewId == j) 
                            btn.setTextColor(Color.BLUE);
                        else
                            btn.setTextColor(Color.BLACK);
                    }

                    //sample data
                    double currentPixelX = 169d;
                    double currentPixelY = 347d;
                    Log.i(tag, " currentPixelX:" + currentPixelX);
                    Log.i(tag, " currentPixelY:" + currentPixelY);

                    int circleSize = 20;
                    Paint currentPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
                    currentPaint.setColor(Color.GREEN);
                    currentPaint.setAlpha(75);

                    String path = new StringBuffer(localMapsPath)
                        .append("/").append(view.getTag()).append(".png").toString();
                    File file = new File(path);
                    InputStream stream = null;
                    try {
                        stream = new FileInputStream(file);
                    } catch (FileNotFoundException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                    Bitmap mapBitmap = BitmapFactory.decodeStream(stream);

                    Canvas canvas = new Canvas(mapBitmap);
                    canvas.drawCircle(
                            Double.valueOf(currentPixelX).floatValue(), 
                            Double.valueOf(currentPixelY).floatValue(),
                            circleSize, currentPaint);

                    iv.setImageBitmap(mapBitmap);
                    iv.invalidate();

                }
            });

            levelLayout.addView(levelButton);
        }
        levelLayout.getChildAt(0).performClick();

    }

}

这是错误内容:

错误/AndroidRuntime(8626):未捕获的处理程序:线程主线程因退出而退出 未捕获的异常错误/AndroidRuntime(8626): java.lang.RuntimeException:无法启动活动 组件信息{com.sample/com.sample.MallMapActivity}: java.lang.IllegalStateException:传递给 Canvas 的不可变位图 *构造函数* ERROR/AndroidRuntime(8626):位于 android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2503) 错误/Android运行时(8626):位于 android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2519) 错误/Android运行时(8626):位于 android.app.ActivityThread.access$2200(ActivityThread.java:123) 错误/Android运行时(8626):位于 android.app.ActivityThread$H.handleMessage(ActivityThread.java:1870) 错误/Android运行时(8626):位于 android.os.Handler.dispatchMessage(Handler.java:99) 错误/AndroidRuntime(8626):位于 android.os.Looper.loop(Looper.java:123) 错误/AndroidRuntime(8626):
在 android.app.ActivityThread.main(ActivityThread.java:4370) 错误/AndroidRuntime(8626):位于 java.lang.reflect.Method.invokeNative(本机方法) 错误/AndroidRuntime(8626):位于 java.lang.reflect.Method.invoke(Method.java:521) 错误/Android运行时(8626):位于 com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868) 错误/Android运行时(8626):位于 com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626) 错误/Android运行时(8626):位于 dalvik.system.NativeStart.main(本机方法) 错误/AndroidRuntime(8626):原因: java.lang.IllegalStateException:传递给 Canvas 的不可变位图 *构造函数* ERROR/AndroidRuntime(8626):位于 android.graphics.Canvas。(Canvas.java:83) 错误/Android运行时(8626):位于 com.sample.MallMapActivity$1.onClick(MallMapActivity.java:110) 错误/AndroidRuntime(8626):位于 android.view.View.performClick(View.java:2397) 错误/AndroidRuntime(8626):位于 com.sample.MallMapActivity.onCreate(MallMapActivity.java:124) 错误/AndroidRuntime(8626):位于 android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047) 错误/AndroidRuntime(8626):位于 android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2466) 错误/AndroidRuntime(8626): ... 11 个以上错误/SemcCheckin(8626): 获取故障转储级别:java.io.FileNotFoundException: /data/semc-checkin/crashdump 错误/SemcCheckin(1544):获取崩溃级别 :java.io.FileNotFoundException:/data/semc-checkin/crashdump

更新:

  1. ma​​pBitmap.isMutable()返回错误值。
  2. 为了使其可变,我更改了代码
位图mapBitmap = BitmapFactory.decodeStream(stream);
位图 newMapBitmap = mapBitmap.copy(Bitmap.Config.ARGB_8888,

真); 画布 canvas = new Canvas(newMapBitmap);

Here's my current code:

public class MallMapActivity extends Activity {
    private final static String tag = "MallMapActivity";
    private ImageView iv;
    private final static String FLOOR = "F";
    private final String storagePath = Environment.getExternalStorageDirectory() + "/appdata23";
    private final String localMapsPath = storagePath + "/localMaps";

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        iv = (ImageView)findViewById(R.id.imageview);
        //iv.setScaleType(ScaleType.FIT_XY);

        final LinearLayout levelLayout = (LinearLayout) findViewById(R.id.level_layout);
        int levelSize = 8;
        for (int i = 0; i < levelSize; i++) {
            Button levelButton = new Button(this.getApplicationContext());
            if(i==0) {
                levelButton.setText(new StringBuffer((i+1)+"").append(FLOOR).append("(start)"));
            } else if (i==7) {
                levelButton.setText(new StringBuffer((i+1)+"").append(FLOOR).append("(end)"));
            } else {
                levelButton.setText(new StringBuffer((i+1)+"").append(FLOOR));
            }
            levelButton.setTag((i+1) + FLOOR);
            levelButton.setId(i);
            levelButton.setLayoutParams(
                    new RadioGroup.LayoutParams(0, RadioGroup.LayoutParams.WRAP_CONTENT, 1));
            levelButton.setOnClickListener(new OnClickListener() {

                @Override
                public void onClick(View view) {
                    int childCount = levelLayout.getChildCount();
                    int viewId = view.getId();

                    for (int j = 0; j < childCount; j++) {
                        Button btn = (Button)levelLayout.getChildAt(j); 
                        if(viewId == j) 
                            btn.setTextColor(Color.BLUE);
                        else
                            btn.setTextColor(Color.BLACK);
                    }

                    //sample data
                    double currentPixelX = 169d;
                    double currentPixelY = 347d;
                    Log.i(tag, " currentPixelX:" + currentPixelX);
                    Log.i(tag, " currentPixelY:" + currentPixelY);

                    int circleSize = 20;
                    Paint currentPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
                    currentPaint.setColor(Color.GREEN);
                    currentPaint.setAlpha(75);

                    String path = new StringBuffer(localMapsPath)
                        .append("/").append(view.getTag()).append(".png").toString();
                    File file = new File(path);
                    InputStream stream = null;
                    try {
                        stream = new FileInputStream(file);
                    } catch (FileNotFoundException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                    Bitmap mapBitmap = BitmapFactory.decodeStream(stream);

                    Canvas canvas = new Canvas(mapBitmap);
                    canvas.drawCircle(
                            Double.valueOf(currentPixelX).floatValue(), 
                            Double.valueOf(currentPixelY).floatValue(),
                            circleSize, currentPaint);

                    iv.setImageBitmap(mapBitmap);
                    iv.invalidate();

                }
            });

            levelLayout.addView(levelButton);
        }
        levelLayout.getChildAt(0).performClick();

    }

}

Here's the error content:

ERROR/AndroidRuntime(8626): Uncaught handler: thread main exiting due
to uncaught exception ERROR/AndroidRuntime(8626):
java.lang.RuntimeException: Unable to start activity
ComponentInfo{com.sample/com.sample.MallMapActivity}:
java.lang.IllegalStateException: Immutable bitmap passed to Canvas
*constructor* ERROR/AndroidRuntime(8626): at
android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2503)
ERROR/AndroidRuntime(8626): at
android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2519)
ERROR/AndroidRuntime(8626): at
android.app.ActivityThread.access$2200(ActivityThread.java:123)
ERROR/AndroidRuntime(8626): at
android.app.ActivityThread$H.handleMessage(ActivityThread.java:1870)
ERROR/AndroidRuntime(8626): at
android.os.Handler.dispatchMessage(Handler.java:99)
ERROR/AndroidRuntime(8626): at
android.os.Looper.loop(Looper.java:123) ERROR/AndroidRuntime(8626):
at android.app.ActivityThread.main(ActivityThread.java:4370)
ERROR/AndroidRuntime(8626): at
java.lang.reflect.Method.invokeNative(Native Method)
ERROR/AndroidRuntime(8626): at
java.lang.reflect.Method.invoke(Method.java:521)
ERROR/AndroidRuntime(8626): at
com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)
ERROR/AndroidRuntime(8626): at
com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
ERROR/AndroidRuntime(8626): at
dalvik.system.NativeStart.main(Native Method)
ERROR/AndroidRuntime(8626): Caused by:
java.lang.IllegalStateException: Immutable bitmap passed to Canvas
*constructor* ERROR/AndroidRuntime(8626): at
android.graphics.Canvas.(Canvas.java:83)
ERROR/AndroidRuntime(8626): at
com.sample.MallMapActivity$1.onClick(MallMapActivity.java:110)
ERROR/AndroidRuntime(8626): at
android.view.View.performClick(View.java:2397)
ERROR/AndroidRuntime(8626): at
com.sample.MallMapActivity.onCreate(MallMapActivity.java:124)
ERROR/AndroidRuntime(8626): at
android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
ERROR/AndroidRuntime(8626): at
android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2466)
ERROR/AndroidRuntime(8626): ... 11 more ERROR/SemcCheckin(8626):
Get crash dump level : java.io.FileNotFoundException:
/data/semc-checkin/crashdump ERROR/SemcCheckin(1544): Get Crash Level
: java.io.FileNotFoundException: /data/semc-checkin/crashdump

UPDATE:

  1. mapBitmap.isMutable() is returning false value.
  2. to make it mutable i changed the code
Bitmap mapBitmap = BitmapFactory.decodeStream(stream);
Bitmap newMapBitmap = mapBitmap.copy(Bitmap.Config.ARGB_8888,

true);
Canvas canvas = new Canvas(newMapBitmap);

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

骷髅 2024-12-10 06:07:31

进行此更改:您无法在不可变位图上绘制,而是可以创建一个

  Bitmap mapBitmap = BitmapFactory.decodeStream(stream);
//make a new mutable  bitmap 
Bitmap map = createBitmap(mapBitmap.getWidth(), mapBitmap.getHeight(),mapBitmap.getConfig());
//copy the pixel to it 
int [] allpixels = new int [ mapBitmap.getHeight()*mapBitmap.getWidth()];

mapBitmap.getPixels(allpixels, 0, mapBitmap.getWidth(), 0, 0, mapBitmap.getWidth(),mapBitmap.getHeight());

map.setPixels(allpixels, 0, mapBitmap.getWidth(), 0, 0, mapBitmap.getWidth(), mapBitmap.getHeight());


                    Canvas canvas = new Canvas(map);

然后开始绘制

make this change : you cant draw on immutable bitmap instead you can create one

  Bitmap mapBitmap = BitmapFactory.decodeStream(stream);
//make a new mutable  bitmap 
Bitmap map = createBitmap(mapBitmap.getWidth(), mapBitmap.getHeight(),mapBitmap.getConfig());
//copy the pixel to it 
int [] allpixels = new int [ mapBitmap.getHeight()*mapBitmap.getWidth()];

mapBitmap.getPixels(allpixels, 0, mapBitmap.getWidth(), 0, 0, mapBitmap.getWidth(),mapBitmap.getHeight());

map.setPixels(allpixels, 0, mapBitmap.getWidth(), 0, 0, mapBitmap.getWidth(), mapBitmap.getHeight());


                    Canvas canvas = new Canvas(map);

then start drawing

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文