Android: Как рисовать фигуры и текст на неподвижном изображении (файл png), а затем помещать в ImageView?

Вот мой текущий код:

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();

    }

}

Вот содержание ошибки:

ОБНОВЛЕНИЕ:

истинный); Холст холст = новый холст (newMapBitmap);

  1. чтобы сделать его изменяемым, я изменил код
  2. внесите это изменение: вы не можете рисовать на неизменяемом растровом изображении, вместо этого вы можете создать его
Bitmap mapBitmap = BitmapFactory.decodeStream(stream);
Bitmap newMapBitmap = mapBitmap.copy(Bitmap.Config.ARGB_8888,

mapBitmap.isMutable () возвращает ложное значение.


person eros    schedule 08.09.2011    source источник


Ответы (1)


затем начни рисовать

  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);

о, круто. у нас была такая же идея. Я прочитал документацию по Android, которая может создать копию изменяемого растрового изображения из исходного растрового изображения (см. обновленный пост выше). Но я думаю о лучшем подходе. или, может быть, внутри они делают то же самое? :)

person confucius    schedule 08.09.2011
comment
ОШИБКА / AndroidRuntime (8626): Неперехваченный обработчик: основной поток завершается из-за неперехваченного исключения. ОШИБКА / AndroidRuntime (8626): java.lang.RuntimeException: невозможно запустить действие ComponentInfo {com.sample / com.sample.MallMapActivity}: java.lang .IllegalStateException: Неизменяемое растровое изображение, переданное в Canvas * конструктор * ERROR / AndroidRuntime (8626): at android.app.ActivityThread.performLaunchActivity (ActivityThread.java:2503) ERROR / AndroidRuntime (8626): в android.app.ActivityThread.handleLaunchActivity (ActivityThread.java:2519) ОШИБКА / AndroidRuntime (8626): в android.app.ActivityThread.access 2200 долларов (ActivityThread.java:123) ОШИБКА / AndroidRuntime (8626): в android.app.ActivityThread $ H.handleMessage (ActivityThread.java:1870) ОШИБКА / AndroidRuntime (8626): в android.os.Handler.dispatchMessage (Handler.java:99) ОШИБКА / AndroidRuntime (8626): в android.os. Looper.loop (Looper.java:123) ОШИБКА / AndroidRuntime (8626):
на android.app.A ctivityThread.main (ActivityThread.java:4370) ОШИБКА / AndroidRuntime (8626): в java.lang.reflect.Method.invokeNative (собственный метод) ОШИБКА / AndroidRuntime (8626): в java.lang.reflect.Method.invoke (Метод .java: 521) ОШИБКА / AndroidRuntime (8626): в com.android.internal.os.ZygoteInit $ MethodAndArgsCaller.run (ZygoteInit.java:868) ОШИБКА / AndroidRuntime (8626): в com.android.internal.os.ZygoteInit .main (ZygoteInit.java:626) ОШИБКА / AndroidRuntime (8626): в dalvik.system.NativeStart.main (собственный метод) ОШИБКА / AndroidRuntime (8626): вызвано: java.lang.IllegalStateException: Неизменяемое растровое изображение передано в Canvas * конструктор * ОШИБКА / AndroidRuntime (8626): в android.graphics.Canvas. (Canvas.java:83) ОШИБКА / AndroidRuntime (8626): в com.sample.MallMapActivity $ 1.onClick (MallMapActivity.java:110) ОШИБКА / AndroidRuntime (8626): в android.view.View.performClick (View.java:2397) ОШИБКА / AndroidRuntime (8626): в com.sample.Mal lMapActivity.onCreate (MallMapActivity.java:124) ОШИБКА / AndroidRuntime (8626): в android.app.Instrumentation.callActivityOnCreate (Instrumentation.java:1047) ОШИБКА / AndroidRuntime (8626): в android.app.ActivityThread.performLaunchActivity (Activity java: 2466) ERROR / AndroidRuntime (8626): ... еще 11 ERROR / SemcCheckin (8626): Получить уровень аварийного дампа: java.io.FileNotFoundException: / data / semc-checkin / crashdump ERROR / SemcCheckin (1544): Get Уровень сбоя: java.io. FileNotFoundException: / данные / semc-checkin / сбой - person eros; 08.09.2011