Более быстрый способ отображения закадрового изображения с помощью Android/ Java

Я начал изучать Android и Java с помощью бета-версии Android Studio. В качестве первого простого тестового приложения я пытаюсь заставить работать базовый рендерер Мандельброта. Я получил это для отображения, но теперь я хочу это быстрее. Кто-нибудь может дать совет по следующему?

  1. Документы говорят, что canvas.drawbitmap устарела. Что я должен использовать вместо этого? Какой самый быстрый способ показать растровое изображение на экране?

  2. Как я могу показать ход расчетов? Если я сниму отметку с 2 строк, помеченных как "обновлять отображение после каждой строки", во время вычислений обновления не будет, и дополнительные вызовы canvas.drawbitmap действительно замедляют все это (79 секунд по сравнению с 31 секундой без нее).

  3. Что я могу сделать, чтобы ускорить общие математические вызовы?

Я постарался сделать его максимально простым для этого примера.

Большое спасибо за любые советы для новичка. Я не хочу изучать вредные привычки с самого начала, если это возможно.

Макет имеет одно изображение, выровненное по экрану. Полный код

import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Point;
import android.os.Bundle;
import android.os.SystemClock;
import android.view.Display;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.widget.ImageView;

import java.text.DecimalFormat;
import java.util.Random;
import static android.graphics.Color.argb;
import static android.graphics.Color.rgb;

public class myActivity extends Activity  {

    myView myview;
    Bitmap bmp;
    Canvas myCanvas;
    ImageView img;
    Paint paint;
    Boolean started=false;
    Integer ih,iw,i,redraws,fw,fh;
    long startms,finishms;
    Random rnd;

    double xmin,xmax,ymin,ymax,padding,bailout,bailout_squared,stepx,stepy,x,y,magnitude;
    double realiters,tweenval;
    Integer col,colval1,colval2;
    Integer iterations,maxiterations,superx,supery,samplepixels,square_samplepixels,xloop,yloop;
    double zr,zi,cr,ci,xloopdouble,yloopdouble;
    int[] colorpalette = new int[256];
    int[] pixels;
    int r,g,b,r1,g1,b1,r2,g2,b2,totalr,totalg,totalb;

    private void init(){
        //screen size
        Display display = getWindowManager().getDefaultDisplay();
        Point sizePoint = new Point();
        paint = new Paint();
        display.getSize(sizePoint);
        iw=sizePoint.x;
        ih=sizePoint.y;
        //pixels array
        fw=iw;
        fh=ih;
        pixels=new int[fw*fh];
        //create bitmap
        bmp=Bitmap.createBitmap(iw, ih, Bitmap.Config.RGB_565);
        //create canvas
        myCanvas =new Canvas();
        myCanvas.setBitmap(bmp);
        img = (ImageView) findViewById(R.id.imageView1);
        rnd = new Random();
    }

    // calculates and displays the Mandelbrot fractal
    private void Mandelbrot(){

        startms= SystemClock.uptimeMillis();

        //coordinates
//        xmin=-1.6345100402832;
//        xmax=-1.63043992784288;
//        ymin=-0.00209962230258512;
//        ymax=0.00209259351094558;
        xmin=-2.3;
        xmax=2.3;
        ymin=-2.1;
        ymax=2.1;

        fw=iw;
        fh=ih;

        //adjust coords to match screen aspect
        if (iw<ih) {
            padding=(xmax-xmin)/iw*(ih-iw);
            ymin=ymin-padding/2.0;
            ymax=ymax+padding/2.0;
        } else {
            padding=(ymax-ymin)/ih*(iw-ih);
            xmin=xmin-padding/2.0;
            xmax=xmax+padding/2.0;
        }

        bailout=8.0; //needs to be higher than default 2 for the CPM coloring to be smooth
        bailout_squared=bailout*bailout;
        maxiterations=64;
        samplepixels=1;
        square_samplepixels=samplepixels*samplepixels;

        //random color palette
        for (col=0;col<256;col++){
            colorpalette[col]=android.graphics.Color.argb(255,rnd.nextInt(256),rnd.nextInt(256),rnd.nextInt(256));
        }

        stepx=(xmax-xmin)/fw/samplepixels;
        stepy=(ymax-ymin)/fh/samplepixels;

        for (yloop=0;yloop<fh;yloop++){
            for (xloop=0;xloop<fw;xloop++){

                totalr=0;
                totalg=0;
                totalb=0;
                r=0;
                g=0;
                b=0;
                xloopdouble=(double)xloop;
                yloopdouble=(double)yloop;

                for (supery=0;supery<samplepixels;supery++)
                {
                    for (superx=0;superx<samplepixels;superx++)
                    {
                        cr = xmin+xloopdouble/(double)fw*(xmax-xmin)+(stepx*(double)superx);
                        ci = ymin+yloopdouble/(double)fh*(ymax-ymin)+(stepy*(double)supery);

                        zr = 0.0;
                        zi = 0.0;
                        magnitude=0.0;

                        for(iterations=0; iterations<maxiterations; iterations++)
                        {
                            i=iterations;

                            x = (zr * zr - zi * zi) + cr;
                            y = (zi * zr + zr * zi) + ci;

                            magnitude=(x * x + y * y);
                            if(magnitude>bailout_squared) break;

                            zr = x;
                            zi = y;
                        }

                        if (iterations>=maxiterations) {
                            r=0;
                            g=0;
                            b=0;
                        } else {
                            //CPM smooth colors
                            realiters=iterations+1-((Math.log(Math.log(Math.sqrt(magnitude)))/Math.log(2.0)));
                            colval1=(int) Math.floor(realiters % 255);
                            colval2=(colval1+1) % 255;
                            tweenval=realiters-Math.floor(realiters);
                            r1=Color.red(colorpalette[colval1]);
                            g1=Color.green(colorpalette[colval1]);
                            b1=Color.blue(colorpalette[colval1]);
                            r2=Color.red(colorpalette[colval2]);
                            g2=Color.green(colorpalette[colval2]);
                            b2=Color.blue(colorpalette[colval2]);
                            r=(int) (r1+((r2-r1)*tweenval));
                            g=(int) (g1+((g2-g1)*tweenval));
                            b=(int) (b1+((b2-b1)*tweenval));
                        }
                        totalr=totalr+r;
                        totalg=totalg+g;
                        totalb=totalb+b;
                    }
                }

                r=(int) totalr/square_samplepixels;
                g=(int) totalg/square_samplepixels;
                b=(int) totalb/square_samplepixels;

                //update pixels array
                pixels[xloop+yloop*fw]=rgb(r, g, b);
            }

            //update display after each line has been calculated
            //myCanvas.drawBitmap(pixels,0,fw,0,0,fw,fh,false,null);
            //if (img != null) img.invalidate();
        }

        myCanvas.drawBitmap(pixels,0,fw,0,0,fw,fh,false,null);
        finishms=SystemClock.uptimeMillis();
    }


    private void updateTimeTaken(){
        //turn antialiasing on
        paint.setAntiAlias(true);
        // draw some text using FILL style
        paint.setStyle(Paint.Style.FILL);
        paint.setTextSize(30);

        DecimalFormat myFormatter = new DecimalFormat("#,###,###");

        paint.setColor(Color.BLACK);
        myCanvas.drawText("Time taken = " + myFormatter.format(finishms - startms) + " ms", 15, 45, paint);
        paint.setColor(Color.WHITE);
        myCanvas.drawText("Time taken = " + myFormatter.format(finishms - startms) + " ms", 14, 44, paint);

        paint.setColor(Color.BLACK);
        myCanvas.drawText("Screen size = " + String.valueOf(iw) + " x " + String.valueOf(ih), 15, 85, paint);
        paint.setColor(Color.WHITE);
        myCanvas.drawText("Screen size = " + String.valueOf(iw) + " x " + String.valueOf(ih), 14, 84, paint);

    }

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        //fullscreen no menu
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);

        redraws=0;
        super.onCreate(savedInstanceState);
        myview = new myView(this);

        setContentView(myview);

        init();

        started=true;

        Mandelbrot();
        updateTimeTaken();

    }

    private class myView extends View{
        public myView(Context context){
            super(context);
        }

        @Override protected void onDraw(Canvas canvas) {
            super.onDraw(canvas);

            //draw off screen bitmap to screen
            if (started==true){
                canvas.drawBitmap(bmp,0,0,paint);
            }

        }

    }
}

0 ответов

Другие вопросы по тегам