Dibujar mapa de bits es lento cuando se escala a alta resolución

I have a really simple task to do which is to draw a background image in a custom View. I create a bitmap and scale it to fit the width and height of the view. This makes the app way slower, like half as fast (I print out the value of time every 10 milliseconds to measure the speed of performance). This is the code:

public class GView extends View {

int w, h;
Bitmap bg;
int time = 0;

boolean created = false;
public GView(Context context) {
    super(context);
    bg = BitmapFactory.decodeResource(getResources(), R.drawable.my_image);
    new Timer();
}

@Override
public void onDraw(Canvas c) {
    Paint p = new Paint();
    if(!created) {
        w=getWidth();
        h=getHeight();
        p.setColor(Color.RED);
        p.setTextSize(40);
        bg = Bitmap.createScaledBitmap(bg, w, h, false);
        created = true;
    }
    if(created) {
        time++;
        c.drawBitmap(bg, 0,0,null);
        c.drawText(time+"", (int)(w/4),  (int)(h/4), p);
    }

}

class Timer extends Handler {
    private Timer() {
        handleMessage(obtainMessage(0));
    }

    @Override
    public void handleMessage(Message m) {
        invalidate();
        sendMessageDelayed(obtainMessage(0), 10);
    }
}

}

FYI, the original image is 300x225. The screen res of my tablet that I scale the image to is 1280x800. The thing is if I scale the background image to sth like (int)(.8*w), (int)(.8*h) or sth smaller or not scale the image at all, then it runs fast as expected.

I tried using ImageView and use setImageResource(R.drawable.my_image) but it was as slow though. I thought drawing an image to fit the background should be very simple for any programming languages, but I've had this problem for a really long time even after a lot of searching. I hope somebody can give me a proper answer. I would really appreciate that.

preguntado el 02 de febrero de 12 a las 10:02

1 Respuestas

createScaledBitmap() should not be done inside your onDraw() routine. It is quite slow because it uses a pixel averaging routine to "smooth" out the stretched bitmap. Create your stretched bitmap outside of the gui thread and then just draw it (canvas.drawBitmap) in your onDraw() method. The filter parameter can be used to create a "nearest neighbor" scaling if set to false. This will look "blocky", but the processing is much faster.

public static Bitmap createScaledBitmap
  (Bitmap src, int dstWidth, int dstHeight, boolean filter)

Respondido 08 Feb 12, 21:02

I call createScaledBitmap() in onDraw() because that is when I can get the width and height of the view. And I only call it once by using if(!created) then call, then set to created = true, then never call createScaledBitmap() again. So it is not bad though. However, I still tried to call it in the constructor, but no difference. - mella

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.