Android颜色更流畅

这有点难以解释我的问题所以我会用几张图片来展示它。 我做了这个位图:

我希望在其中绘制一个光圈,使用以下代码:

Rect bounds1 = new Rect(x, y, x+bit.getWidth(), y+bit.getHeight()); for (int i = bounds1.left; i < bounds1.right; i++) { for (int j = bounds1.top; j < bounds1.bottom; j++) { int result=(int) Math.sqrt((x2-i)*(x2-i)+(y2-j)*(y2-j)); if(result= 256) { r = 255; } else if (r = 256) { g = 255; } else if (g = 256) { b = 255; } else if (b < 0) { b = 0; } bit.setPixel(ix, jy, Color.argb(a,r, g, b)); } } 

我设法创造了这个:

现在,我正在尝试使光球更平滑而不那么粗糙所以它看起来不像一个圆圈,任何人都知道我该怎么做? 我尝试了很多东西,但没有成功。

整个绘图代码:

 public class CreatorView extends View 

{

 Context c; boolean quickfix=false; boolean bin_isEmpty=true; boolean iftrue=false; boolean stopnow=false; boolean buttonpressed=false; String arrowcheck=""; int screenw; int screenh; int pixelx; int pixely; int smallpixelx; int smallpixely; Point arrowsp; Paint paintblock; int currentColor=0; int x2=120; int y2=120; int rn=60; int gn=45; int bn=30; Bitmap tileBitmap; Bitmap lightBitmap; RectF lightRect; Paint paint0 = new Paint(Paint.ANTI_ALIAS_FLAG); Paint paint1 = new Paint(Paint.ANTI_ALIAS_FLAG); Bitmap mountaintop; Bitmap mountainbottom; Bitmap grass; Bitmap dirt; Bitmap dirt2; Bitmap dirt3; Bitmap stonegrass; Bitmap stone; Bitmap stone2; Bitmap stone3; Bitmap stone4; Bitmap cloud; Bitmap bin_Empty; Bitmap bin_Full; Bitmap arrowno; Bitmap arrown; Bitmap arrowl; Bitmap arrowr; Bitmap arrowu; Bitmap arrowd; Bitmap arrowul; Bitmap arrowur; Bitmap save; Bitmap fliph; Bitmap flipv; Bitmap Rotatef; Bitmap Rotateb; Bitmap arrowdl; Bitmap arrowdr; Bitmap grassSide; Bitmap grassTop; Bitmap orange; Bitmap blue; Bitmap smallpixel; Bitmap PixelDetect; Bitmap colorpick; Bitmap brush; Bitmap brushcolor; Bitmap torch; Map.EntrycurrentBlock; Map.EntrylastBlock; Map grassblock = new HashMap(); Map stonegrassblock = new HashMap(); Map dirtblock = new HashMap(); Map stoneblock = new HashMap(); Map grassSideBlock = new HashMap(); Map grassTopBlock = new HashMap(); Map orangeBlock = new HashMap(); Map blueBlock = new HashMap(); Map mountaintopBack = new HashMap(); Map mountainbottomBack = new HashMap(); Map torchBack = new HashMap(); Map levelMap = new HashMap(); ListmenuButtonList=new ArrayList(); public CreatorView(Context c) { super(c); this.c=c; WindowManager wm = (WindowManager) c.getSystemService(Context.WINDOW_SERVICE); Display display = wm.getDefaultDisplay(); this.screenw= display.getWidth(); this.screenh=display.getHeight(); this.PixelDetect = BitmapFactory.decodeResource( getResources(), R.drawable.custom_pixel); this.smallpixel = Bitmap.createScaledBitmap(PixelDetect, 3, 3, false); this.grass=BitmapFactory.decodeResource(getResources(), R.drawable.block_grass); this.grassSide=BitmapFactory.decodeResource(getResources(), R.drawable.block_grassside); this.grassTop=BitmapFactory.decodeResource(getResources(), R.drawable.block_grasstop); this.orange=BitmapFactory.decodeResource(getResources(), R.drawable.block_cube1); this.blue=BitmapFactory.decodeResource(getResources(), R.drawable.block_bluecube); this.dirt=BitmapFactory.decodeResource(getResources(), R.drawable.block_dirt); this.dirt2=BitmapFactory.decodeResource(getResources(), R.drawable.block_dirt2); this.dirt3=BitmapFactory.decodeResource(getResources(), R.drawable.block_dirt3); this.stonegrass=BitmapFactory.decodeResource(getResources(), R.drawable.block_stonegrass); this.stone=BitmapFactory.decodeResource(getResources(), R.drawable.block_stone); this.stone2=BitmapFactory.decodeResource(getResources(), R.drawable.block_stone2); this.stone3=BitmapFactory.decodeResource(getResources(), R.drawable.block_stone3); this.stone4=BitmapFactory.decodeResource(getResources(), R.drawable.block_stone4); this.mountaintop=BitmapFactory.decodeResource(getResources(), R.drawable.back_mountaintop); this.mountainbottom=BitmapFactory.decodeResource(getResources(), R.drawable.back_mountainbottom); this.arrowno=BitmapFactory.decodeResource(getResources(), R.drawable.arrow_noclick); this.arrown=BitmapFactory.decodeResource(getResources(), R.drawable.arrow_normal); this.arrowl=BitmapFactory.decodeResource(getResources(), R.drawable.arrow_left); this.arrowr=BitmapFactory.decodeResource(getResources(), R.drawable.arrow_right); this.arrowu=BitmapFactory.decodeResource(getResources(), R.drawable.arrow_up); this.arrowd=BitmapFactory.decodeResource(getResources(), R.drawable.arrow_down); this.arrowul=BitmapFactory.decodeResource(getResources(), R.drawable.arrow_upperleft); this.arrowur=BitmapFactory.decodeResource(getResources(), R.drawable.arrow_upperright); this.arrowdl=BitmapFactory.decodeResource(getResources(), R.drawable.arrow_downleft); this.arrowdr=BitmapFactory.decodeResource(getResources(), R.drawable.arrow_downright); this.arrowno=Bitmap.createScaledBitmap(arrowno, arrowno.getWidth()*3, arrowno.getHeight()*3, false); this.save=BitmapFactory.decodeResource(getResources(), R.drawable.button_save); this.brush=BitmapFactory.decodeResource(getResources(), R.drawable.menu_brush); this.brushcolor=BitmapFactory.decodeResource(getResources(), R.drawable.menu_brush_color); this.colorpick=BitmapFactory.decodeResource(getResources(), R.drawable.menu_colorpicker); this.torch=BitmapFactory.decodeResource(getResources(), R.drawable.item_torch); this.save=BitmapFactory.decodeResource(getResources(), R.drawable.button_save); this.fliph=BitmapFactory.decodeResource(getResources(), R.drawable.menu_fliph); this.flipv=BitmapFactory.decodeResource(getResources(), R.drawable.menu_flipv); this.Rotatef=BitmapFactory.decodeResource(getResources(), R.drawable.menu_rotatef); this.Rotateb=BitmapFactory.decodeResource(getResources(), R.drawable.menu_rotateb); this.bin_Empty=BitmapFactory.decodeResource(getResources(), R.drawable.bin_empty); this.bin_Full=BitmapFactory.decodeResource(getResources(), R.drawable.bin_full); this.bin_Empty=Bitmap.createScaledBitmap(bin_Empty, bin_Empty.getWidth()*3, bin_Empty.getHeight()*3, false); this.bin_Full=Bitmap.createScaledBitmap(bin_Full, bin_Full.getWidth()*3, bin_Full.getHeight()*3, false); this.brush=Bitmap.createScaledBitmap(brush, brush.getWidth()*3, brush.getHeight()*3, false); this.brushcolor=Bitmap.createScaledBitmap(brushcolor, brushcolor.getWidth()*3, brushcolor.getHeight()*3, false); this.colorpick=Bitmap.createScaledBitmap(colorpick, colorpick.getWidth()*3, colorpick.getHeight()*3, false); this.fliph=Bitmap.createScaledBitmap(fliph, fliph.getWidth()*3, fliph.getHeight()*3, false); this.flipv=Bitmap.createScaledBitmap(flipv, flipv.getWidth()*3, flipv.getHeight()*3, false); this.Rotateb=Bitmap.createScaledBitmap(Rotateb, Rotateb.getWidth()*3, Rotateb.getHeight()*3, false); this.Rotatef=Bitmap.createScaledBitmap(Rotatef, Rotatef.getWidth()*3, Rotatef.getHeight()*3, false); this.arrown=Bitmap.createScaledBitmap(arrown, arrown.getWidth()*3, arrown.getHeight()*3, false); this.arrowl=Bitmap.createScaledBitmap(arrowl, arrowl.getWidth()*3, arrowl.getHeight()*3, false); this.arrowr=Bitmap.createScaledBitmap(arrowr, arrowr.getWidth()*3, arrowr.getHeight()*3, false); this.arrowu=Bitmap.createScaledBitmap(arrowu, arrowu.getWidth()*3, arrowu.getHeight()*3, false); this.arrowd=Bitmap.createScaledBitmap(arrowd, arrowd.getWidth()*3, arrowd.getHeight()*3, false); this.arrowul=Bitmap.createScaledBitmap(arrowul, arrowul.getWidth()*3, arrowul.getHeight()*3, false); this.arrowur=Bitmap.createScaledBitmap(arrowur, arrowur.getWidth()*3, arrowur.getHeight()*3, false); this.arrowdl=Bitmap.createScaledBitmap(arrowdl, arrowdl.getWidth()*3, arrowdl.getHeight()*3, false); this.arrowdr=Bitmap.createScaledBitmap(arrowdr, arrowdr.getWidth()*3, arrowdr.getHeight()*3, false); Menu_Add(arrowno,0,true,"arrows"); Menu_Add(bin_Empty,1,false,"bin"); Menu_Add(brush,2,false,"brush"); Menu_Add(brushcolor,2,false,"brushcolor"); Menu_Add(colorpick,3,false,"colorpick"); Menu_Add(Rotateb,4,false,"rotateb"); Menu_Add(Rotatef,5,false,"rotatef"); Menu_Add(fliph,6,false,"fliph"); Menu_Add(flipv,7,false,"flipv"); Menu_Add(grassTop,1,true,"grasstop"); Menu_Add(grassSide,2,true,"grassside"); Menu_Add(grass,3,true,"grass"); Menu_Add(dirt,4,true,"dirt"); Menu_Add(stonegrass,5,true,"stonegrass"); Menu_Add(stone,6,true,"stone"); Menu_Add(orange,7,true,"orange"); Menu_Add(blue,8,true,"blue"); Menu_Add(mountaintop,9,true,"mountaintop"); Menu_Add(mountainbottom,10,true,"mountainbottom"); Menu_Add(torch,11,true,"torch"); arrowsp=new Point(); arrowsp.x=0; arrowsp.y=0; tileBitmap = grass; } private void Menu_Add(Bitmap b,int order,boolean vertical,String name) { Point p=new Point(); if(order==0){ px=0; py=0; MenuButton m=new MenuButton(order,b , vertical, p,name); menuButtonList.add(m); } else{ for (MenuButton m : menuButtonList) { if((m.isVertical()==vertical||order==1)&&m.getOrder()+1==order ){ if(vertical){ px=0; py=m.getP().y+m.getBit().getHeight()+2; } else{ px=m.getP().x+m.getBit().getWidth()+2; py=0; } MenuButton m2=new MenuButton(order,b , vertical, p,name); menuButtonList.add(m2); return; } } } } public void drawLight(){ lightBitmap = Bitmap.createBitmap(1500, 15000, Bitmap.Config.ARGB_8888); Canvas cc = new Canvas(lightBitmap); Paint pp = new Paint(Paint.ANTI_ALIAS_FLAG); pp.setMaskFilter(new BlurMaskFilter(20, BlurMaskFilter.Blur.NORMAL)); for (Map.Entry entry : torchBack.entrySet()) { cc.drawCircle(entry.getValue().x+6, entry.getValue().y+55, 25, pp); } lightRect = new RectF(-256, -256, lightBitmap.getWidth(), lightBitmap.getHeight()); lightRect.offset(200, 200); float[] array = { 1.2f, 0, 0, 0, 1, 0,1.2f, 0, 0, 1, 0, 0, 1.2f, 0, 1, 0, 0, 0, 1, 0, }; ColorMatrix ccc=new ColorMatrix(array); ccc.setScale(2, 1.5f, 1f, 1f); ColorMatrixColorFilter c4=new ColorMatrixColorFilter(ccc); paint0.setColorFilter(c4); paint1.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN)); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); drawLight(); Paint paintAlpha = new Paint(); paintAlpha.setAlpha(200); canvas.drawARGB(255, 86, 194, 243); drawTiles(canvas, paint0); drawTiles(canvas, null); for(MenuButton m : menuButtonList){ switch(m.getName()){ case "bin": if(bin_isEmpty){ canvas.drawBitmap(bin_Empty, m.getP().x, m.getP().y,paintAlpha); } else{ canvas.drawBitmap(bin_Full, m.getP().x, m.getP().y,paintAlpha); } break; case "brushcolor": canvas.drawBitmap(m.getBit(), m.getP().x,m.getP().y, changeBitmapColor(m.getBit(), currentColor)); break; case "arrows": canvas.drawBitmap(m.getBit(),m.getP().x,m.getP().y,paintAlpha); switch (arrowcheck) { case "normal": canvas.drawBitmap(arrown, arrowsp.x, arrowsp.y,paintAlpha); break; case "left": canvas.drawBitmap(arrowl, arrowsp.x, arrowsp.y,paintAlpha); break; case "right": canvas.drawBitmap(arrowr, arrowsp.x, arrowsp.y,paintAlpha); break; case "down": canvas.drawBitmap(arrowd, arrowsp.x, arrowsp.y,paintAlpha); break; case "up": canvas.drawBitmap(arrowu, arrowsp.x, arrowsp.y,paintAlpha); break; case "upleft": canvas.drawBitmap(arrowul, arrowsp.x, arrowsp.y,paintAlpha); break; case "upright": canvas.drawBitmap(arrowur, arrowsp.x, arrowsp.y,paintAlpha); break; case "downleft": canvas.drawBitmap(arrowdl, arrowsp.x, arrowsp.y,paintAlpha); break; case "downright": canvas.drawBitmap(arrowdr, arrowsp.x, arrowsp.y,paintAlpha); break; } break; default: canvas.drawBitmap(m.getBit(),m.getP().x,m.getP().y,paintAlpha); break; } Paint paintRec = new Paint(); paintRec.setColor(Color.RED); paintRec.setStyle(Style.STROKE); paintRec.setStrokeWidth(4); paintRec.setStrokeCap(Cap.ROUND); paintRec.setStrokeJoin(Join.ROUND); paintRec.setPathEffect(new DashPathEffect(new float[] {30,40}, 0)); paintRec.setAlpha(5); if(currentBlock!=null) canvas.drawRect(currentBlock.getValue().x,currentBlock.getValue().y,currentBlock.getValue().x+currentBlock.getKey().getBit().getWidth(),currentBlock.getValue().y+currentBlock.getKey().getBit().getHeight(),paintRec); } canvas.saveLayer(lightRect, null, Canvas.HAS_ALPHA_LAYER_SAVE_FLAG); canvas.clipRect(lightRect); drawTiles(canvas, paint0); canvas.drawBitmap(lightBitmap, null, lightRect, paint1); canvas.restore(); } void drawTiles(Canvas canvas, Paint p) { for (Map.Entry entry : mountainbottomBack.entrySet()) { //Bitmap lighten=Bitmap.createScaledBitmap(entry.getKey().getBit(), entry.getKey().getBit().getWidth(), entry.getKey().getBit().getHeight(), false); canvas.drawBitmap(entry.getKey().getBit(), entry.getValue().x,entry.getValue().y, p); } for (Map.Entry entry : mountaintopBack.entrySet()) { canvas.drawBitmap(entry.getKey().getBit(), entry.getValue().x,entry.getValue().y, p); } for (Map.Entry entry : grassblock.entrySet()) { canvas.drawBitmap(entry.getKey().getBit(), entry.getValue().x,entry.getValue().y, p); } for (Map.Entry entry : stonegrassblock.entrySet()) { canvas.drawBitmap(entry.getKey().getBit(), entry.getValue().x,entry.getValue().y, p); } for (Map.Entry entry : dirtblock.entrySet()) { canvas.drawBitmap(entry.getKey().getBit(), entry.getValue().x,entry.getValue().y, p); } for (Map.Entry entry : stoneblock.entrySet()) { canvas.drawBitmap(entry.getKey().getBit(), entry.getValue().x,entry.getValue().y, p); } for (Map.Entry entry : grassSideBlock.entrySet()) { canvas.drawBitmap(entry.getKey().getBit(), entry.getValue().x,entry.getValue().y, p); } for (Map.Entry entry : grassTopBlock.entrySet()) { canvas.drawBitmap(entry.getKey().getBit(), entry.getValue().x,entry.getValue().y, p); } for (Map.Entry entry : orangeBlock.entrySet()) { canvas.drawBitmap(entry.getKey().getBit(), entry.getValue().x,entry.getValue().y, p); } for (Map.Entry entry : blueBlock.entrySet()) { canvas.drawBitmap(entry.getKey().getBit(), entry.getValue().x,entry.getValue().y, p); } for (Map.Entry entry : torchBack.entrySet()) { canvas.drawBitmap(entry.getKey().getBit(), entry.getValue().x,entry.getValue().y, p); } } 

使用这个自定义View,使其更黄色看到float []数组初始化中的注释:

 class V extends View { Paint paint0; Paint paint1; public V(Context context) { super(context); setLayerType(View.LAYER_TYPE_SOFTWARE, null); paint0 = new Paint(); Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.fykgf); Shader shader = new BitmapShader(bitmap, Shader.TileMode.REPEAT, Shader.TileMode.REPEAT); paint0.setShader(shader); paint1 = new Paint(); paint1.setMaskFilter(new BlurMaskFilter(50, BlurMaskFilter.Blur.NORMAL)); float[] array = { 2, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 2, 0, 0, // change 2 to: something between [1..2] to get it more yellow 0, 0, 0, 1, 0, }; paint1.setColorFilter(new ColorMatrixColorFilter(array)); paint1.setShader(shader); } @Override protected void onDraw(Canvas canvas) { canvas.drawRect(0, 0, getWidth(), getHeight(), paint0); canvas.drawCircle(300, 300, 150, paint1); } } 

编辑

如果你想绘制几个Bitmapts ,请使用:

 class V extends View { Bitmap tileBitmap; Bitmap lightBitmap; RectF lightRect; Paint paint0 = new Paint(Paint.ANTI_ALIAS_FLAG); Paint paint1 = new Paint(Paint.ANTI_ALIAS_FLAG); public V(Context context) { super(context); // setLayerType(View.LAYER_TYPE_SOFTWARE, null); tileBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.fykgf); lightBitmap = Bitmap.createBitmap(256, 256, Bitmap.Config.ARGB_8888); Canvas c = new Canvas(lightBitmap); Paint p = new Paint(Paint.ANTI_ALIAS_FLAG); p.setMaskFilter(new BlurMaskFilter(20, BlurMaskFilter.Blur.NORMAL)); c.drawCircle(128, 128, 100, p); lightRect = new RectF(0, 0, lightBitmap.getWidth(), lightBitmap.getHeight()); lightRect.offset(200, 200); float[] array = { 4, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, }; paint0.setColorFilter(new ColorMatrixColorFilter(array)); paint1.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN)); } @Override protected void onDraw(Canvas canvas) { drawTiles(canvas, null); canvas.saveLayer(lightRect, null, Canvas.HAS_ALPHA_LAYER_SAVE_FLAG); canvas.clipRect(lightRect); drawTiles(canvas, paint0); canvas.drawBitmap(lightBitmap, null, lightRect, paint1); canvas.restore(); } void drawTiles(Canvas canvas, Paint p) { // draw your Bitmaps here... } } 

我同意其他海报的说法,即使用内置的Android图形function是一种更好,更有效的方法来解决这个问题,但如果这只是为了学习目的,我没有看到操纵原始像素值的危害直。 我只会给你一些想法,而不是提供一个完整的解决方案。

目前,您正在有效地将纹理与恒定的浅色(rn,gn,bn)进行添加混合。 为了更顺利地执行此操作,请引入alpha值,以便您将(rn * a,gn * a,bn * a)添加到纹理中,并根据径向距离改变alpha。

注意,这不是使用Color.alpha(像素)从纹理获得的alpha值,而是另一个用于表示光强度的alpha值。

隐含地,如果结果 (您计算的距光中心的距离)<= 120,则当前的alpha值定义为1,否则为零:它是全有或全无。

您可以根据结果定义一个函数,以在这些极端值之间给出alpha值。 例如,如果半径小于90,则可以使alpha值为1,然后将半径从90减小到零,从半径= 90渐变到半径= 150,然后将其调整为零。

为了方便编码,您还可以缩放alpha值,使其从0(无光)到256(全光强度)而不是0到1。

根据以上规则计算这样的alpha值函数:

 int result=(int) Math.sqrt((x2-i)*(x2-i)+(y2-j)*(y2-j)); int alpha = 0; if(result <= 90) alpha = 256; else if((result > 90) && (result < 150)) alpha = ((60 - (result - 90)) * 256) / 60; 

显然,你可以使用这些值来获得你喜欢的效果。

然后,而不是测试

 if(result<=120) 

像这样测试alpha值

 if(alpha > 0) 

最后,在你的循环中,将rn,gn和bn添加到像素颜色值,这样当alpha = 0时你不添加任何东西,当alpha = 256你添加整个数量时,你为它们之间的每个值添加部分金额。 我会让你弄清楚如何自己做这件事。