Более быстрый способ отображения закадрового изображения с помощью Android/ Java
Я начал изучать Android и Java с помощью бета-версии Android Studio. В качестве первого простого тестового приложения я пытаюсь заставить работать базовый рендерер Мандельброта. Я получил это для отображения, но теперь я хочу это быстрее. Кто-нибудь может дать совет по следующему?
Документы говорят, что canvas.drawbitmap устарела. Что я должен использовать вместо этого? Какой самый быстрый способ показать растровое изображение на экране?
Как я могу показать ход расчетов? Если я сниму отметку с 2 строк, помеченных как "обновлять отображение после каждой строки", во время вычислений обновления не будет, и дополнительные вызовы canvas.drawbitmap действительно замедляют все это (79 секунд по сравнению с 31 секундой без нее).
Что я могу сделать, чтобы ускорить общие математические вызовы?
Я постарался сделать его максимально простым для этого примера.
Большое спасибо за любые советы для новичка. Я не хочу изучать вредные привычки с самого начала, если это возможно.
Макет имеет одно изображение, выровненное по экрану. Полный код
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);
}
}
}
}