Android 颜色更平滑
Android color smoother
很难解释我的问题,所以我会用几张图片来展示它。我做了这个位图:
我想在里面画一圈光,使用这个代码:
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<=120){
int pixel = (bit.getPixel(i-x,j-y));
int a,r, g, b;
int different=result/10;
//change the value of each component
a=Color.alpha(pixel);
r = Color.red(pixel) + rn;
g = Color.green(pixel) + gn;
b = Color.blue(pixel) + bn;
//r,g,b values which are out of the range 0 to 255 should set to 0 or 255
if (r >= 256) {
r = 255;
} else if (r < 0) {
r = 0;
}
if (g >= 256) {
g = 255;
} else if (g < 0) {
g = 0;
}
if (b >= 256) {
b = 255;
} else if (b < 0) {
b = 0;
}
bit.setPixel(i-x, j-y, 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.Entry<CreatorBlock,Point>currentBlock;
Map.Entry<CreatorBlock,Point>lastBlock;
Map<CreatorBlock, Point> grassblock = new HashMap<CreatorBlock, Point>();
Map<CreatorBlock, Point> stonegrassblock = new HashMap<CreatorBlock, Point>();
Map<CreatorBlock, Point> dirtblock = new HashMap<CreatorBlock, Point>();
Map<CreatorBlock, Point> stoneblock = new HashMap<CreatorBlock, Point>();
Map<CreatorBlock, Point> grassSideBlock = new HashMap<CreatorBlock, Point>();
Map<CreatorBlock, Point> grassTopBlock = new HashMap<CreatorBlock, Point>();
Map<CreatorBlock, Point> orangeBlock = new HashMap<CreatorBlock, Point>();
Map<CreatorBlock, Point> blueBlock = new HashMap<CreatorBlock, Point>();
Map<BackBlock, Point> mountaintopBack = new HashMap<BackBlock, Point>();
Map<BackBlock, Point> mountainbottomBack = new HashMap<BackBlock, Point>();
Map<BackBlock, Point> torchBack = new HashMap<BackBlock, Point>();
Map<CreatorBlock, Point> levelMap = new HashMap<CreatorBlock, Point>();
List<MenuButton>menuButtonList=new ArrayList<MenuButton>();
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){
p.x=0;
p.y=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){
p.x=0;
p.y=m.getP().y+m.getBit().getHeight()+2;
}
else{
p.x=m.getP().x+m.getBit().getWidth()+2;
p.y=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<BackBlock, Point> 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<BackBlock, Point> 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<BackBlock, Point> entry : mountaintopBack.entrySet()) {
canvas.drawBitmap(entry.getKey().getBit(), entry.getValue().x,entry.getValue().y, p);
}
for (Map.Entry<CreatorBlock, Point> entry : grassblock.entrySet()) {
canvas.drawBitmap(entry.getKey().getBit(), entry.getValue().x,entry.getValue().y, p);
}
for (Map.Entry<CreatorBlock, Point> entry : stonegrassblock.entrySet()) {
canvas.drawBitmap(entry.getKey().getBit(), entry.getValue().x,entry.getValue().y, p);
}
for (Map.Entry<CreatorBlock, Point> entry : dirtblock.entrySet()) {
canvas.drawBitmap(entry.getKey().getBit(), entry.getValue().x,entry.getValue().y, p);
}
for (Map.Entry<CreatorBlock, Point> entry : stoneblock.entrySet()) {
canvas.drawBitmap(entry.getKey().getBit(), entry.getValue().x,entry.getValue().y, p);
}
for (Map.Entry<CreatorBlock, Point> entry : grassSideBlock.entrySet()) {
canvas.drawBitmap(entry.getKey().getBit(), entry.getValue().x,entry.getValue().y, p);
}
for (Map.Entry<CreatorBlock, Point> entry : grassTopBlock.entrySet()) {
canvas.drawBitmap(entry.getKey().getBit(), entry.getValue().x,entry.getValue().y, p);
}
for (Map.Entry<CreatorBlock, Point> entry : orangeBlock.entrySet()) {
canvas.drawBitmap(entry.getKey().getBit(), entry.getValue().x,entry.getValue().y, p);
}
for (Map.Entry<CreatorBlock, Point> entry : blueBlock.entrySet()) {
canvas.drawBitmap(entry.getKey().getBit(), entry.getValue().x,entry.getValue().y, p);
}
for (Map.Entry<BackBlock, Point> entry : torchBack.entrySet()) {
canvas.drawBitmap(entry.getKey().getBit(), entry.getValue().x,entry.getValue().y, p);
}
}
我同意其他发帖者的说法,他们说使用内置的 Android 图形函数是解决这个问题的更好、更有效的方法,但如果这只是为了学习目的,我不会查看直接操作原始像素值的危害。我只是给你一些想法,而不是提供一个完整的解决方案。
目前,您正在有效地对纹理和恒定的浅色 (rn, gn, bn) 进行叠加混合。为了更顺利地做到这一点,引入一个 alpha 值,这样你就可以将 (rn * a, gn * a, bn * a) 添加到你的纹理中,并根据径向距离改变 alpha。
请注意,这不是您从具有 Color.alpha(像素)的纹理中获得的 alpha 值,而是另一个代表光线强度的值。
隐含地,如果 result(您计算出的与光中心的距离)<= 120,则您当前的 alpha 值定义为 1,否则为零:它是全或-没什么。
您可以根据 result 定义一个函数,以给出介于这些极端值之间的 alpha 值。例如,如果半径小于 90,您可以将 alpha 值设置为 1,然后将其从 1 逐渐降低到 0,从 radius = 90 到 radius = 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 时你添加全部量,并且你为每个添加部分量之间的值。我会让你自己弄清楚如何做到这一点。
使用这个自定义View,让它更黄见float[] array initialization中的注释:
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...
}
}
很难解释我的问题,所以我会用几张图片来展示它。我做了这个位图:
我想在里面画一圈光,使用这个代码:
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<=120){
int pixel = (bit.getPixel(i-x,j-y));
int a,r, g, b;
int different=result/10;
//change the value of each component
a=Color.alpha(pixel);
r = Color.red(pixel) + rn;
g = Color.green(pixel) + gn;
b = Color.blue(pixel) + bn;
//r,g,b values which are out of the range 0 to 255 should set to 0 or 255
if (r >= 256) {
r = 255;
} else if (r < 0) {
r = 0;
}
if (g >= 256) {
g = 255;
} else if (g < 0) {
g = 0;
}
if (b >= 256) {
b = 255;
} else if (b < 0) {
b = 0;
}
bit.setPixel(i-x, j-y, 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.Entry<CreatorBlock,Point>currentBlock;
Map.Entry<CreatorBlock,Point>lastBlock;
Map<CreatorBlock, Point> grassblock = new HashMap<CreatorBlock, Point>();
Map<CreatorBlock, Point> stonegrassblock = new HashMap<CreatorBlock, Point>();
Map<CreatorBlock, Point> dirtblock = new HashMap<CreatorBlock, Point>();
Map<CreatorBlock, Point> stoneblock = new HashMap<CreatorBlock, Point>();
Map<CreatorBlock, Point> grassSideBlock = new HashMap<CreatorBlock, Point>();
Map<CreatorBlock, Point> grassTopBlock = new HashMap<CreatorBlock, Point>();
Map<CreatorBlock, Point> orangeBlock = new HashMap<CreatorBlock, Point>();
Map<CreatorBlock, Point> blueBlock = new HashMap<CreatorBlock, Point>();
Map<BackBlock, Point> mountaintopBack = new HashMap<BackBlock, Point>();
Map<BackBlock, Point> mountainbottomBack = new HashMap<BackBlock, Point>();
Map<BackBlock, Point> torchBack = new HashMap<BackBlock, Point>();
Map<CreatorBlock, Point> levelMap = new HashMap<CreatorBlock, Point>();
List<MenuButton>menuButtonList=new ArrayList<MenuButton>();
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){
p.x=0;
p.y=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){
p.x=0;
p.y=m.getP().y+m.getBit().getHeight()+2;
}
else{
p.x=m.getP().x+m.getBit().getWidth()+2;
p.y=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<BackBlock, Point> 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<BackBlock, Point> 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<BackBlock, Point> entry : mountaintopBack.entrySet()) {
canvas.drawBitmap(entry.getKey().getBit(), entry.getValue().x,entry.getValue().y, p);
}
for (Map.Entry<CreatorBlock, Point> entry : grassblock.entrySet()) {
canvas.drawBitmap(entry.getKey().getBit(), entry.getValue().x,entry.getValue().y, p);
}
for (Map.Entry<CreatorBlock, Point> entry : stonegrassblock.entrySet()) {
canvas.drawBitmap(entry.getKey().getBit(), entry.getValue().x,entry.getValue().y, p);
}
for (Map.Entry<CreatorBlock, Point> entry : dirtblock.entrySet()) {
canvas.drawBitmap(entry.getKey().getBit(), entry.getValue().x,entry.getValue().y, p);
}
for (Map.Entry<CreatorBlock, Point> entry : stoneblock.entrySet()) {
canvas.drawBitmap(entry.getKey().getBit(), entry.getValue().x,entry.getValue().y, p);
}
for (Map.Entry<CreatorBlock, Point> entry : grassSideBlock.entrySet()) {
canvas.drawBitmap(entry.getKey().getBit(), entry.getValue().x,entry.getValue().y, p);
}
for (Map.Entry<CreatorBlock, Point> entry : grassTopBlock.entrySet()) {
canvas.drawBitmap(entry.getKey().getBit(), entry.getValue().x,entry.getValue().y, p);
}
for (Map.Entry<CreatorBlock, Point> entry : orangeBlock.entrySet()) {
canvas.drawBitmap(entry.getKey().getBit(), entry.getValue().x,entry.getValue().y, p);
}
for (Map.Entry<CreatorBlock, Point> entry : blueBlock.entrySet()) {
canvas.drawBitmap(entry.getKey().getBit(), entry.getValue().x,entry.getValue().y, p);
}
for (Map.Entry<BackBlock, Point> entry : torchBack.entrySet()) {
canvas.drawBitmap(entry.getKey().getBit(), entry.getValue().x,entry.getValue().y, p);
}
}
我同意其他发帖者的说法,他们说使用内置的 Android 图形函数是解决这个问题的更好、更有效的方法,但如果这只是为了学习目的,我不会查看直接操作原始像素值的危害。我只是给你一些想法,而不是提供一个完整的解决方案。
目前,您正在有效地对纹理和恒定的浅色 (rn, gn, bn) 进行叠加混合。为了更顺利地做到这一点,引入一个 alpha 值,这样你就可以将 (rn * a, gn * a, bn * a) 添加到你的纹理中,并根据径向距离改变 alpha。
请注意,这不是您从具有 Color.alpha(像素)的纹理中获得的 alpha 值,而是另一个代表光线强度的值。
隐含地,如果 result(您计算出的与光中心的距离)<= 120,则您当前的 alpha 值定义为 1,否则为零:它是全或-没什么。
您可以根据 result 定义一个函数,以给出介于这些极端值之间的 alpha 值。例如,如果半径小于 90,您可以将 alpha 值设置为 1,然后将其从 1 逐渐降低到 0,从 radius = 90 到 radius = 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 时你添加全部量,并且你为每个添加部分量之间的值。我会让你自己弄清楚如何做到这一点。
使用这个自定义View,让它更黄见float[] array initialization中的注释:
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...
}
}