gpt4 book ai didi

android - 修改 android drawable 的颜色

转载 作者:IT老高 更新时间:2023-10-28 13:22:19 38 4
gpt4 key购买 nike

我希望能够使用相同的可绘制对象来表示两者:

Blue iconRed icon

作为同一个drawable,并根据一些编程值重新着色drawable,以便最终用户可以重新主题化界面。

最好的方法是什么?我已经尝试(并重用了来自)this previous S.O. question 的图标但我不能将这种变化表示为简单的色调变化,因为它的饱和度和值也有所不同..

最好将图标存储为我想要更改的区域中的全白?还是透明的?还是其他纯色?

有什么方法可以让你根据 red_icon 的颜色和 blue_icon 的颜色之间的差异来计算矩阵吗?

最佳答案

所以经过大量的试验和错误,阅读不同的文章,最重要的是,通过 API Demos(ColorFilters.java - com.example.android.apis.graphics 中找到)我找到了解决方案。

对于纯色图像,我发现最好使用颜色过滤器 PorterDuff.Mode.SRC_ATOP,因为它会将颜色覆盖在源图像之上,允许您将颜色更改为您正在寻找的确切颜色.

对于更复杂的图像,例如上面的图像,我发现最好的办法是将整个图像着色为白色 (FFFFFF),这样当您执行 PorterDuff.Mode.MULTIPLY 时,您最终会得到正确的颜色,并且图像中的所有黑色 (000000) 都将保持黑色。

colorfilters.java 向您展示了如果您在 Canvas 上绘图,它是如何完成的,但如果您只需要为可绘制对象着色,那么这将起作用:

COLOR2 = Color.parseColor("#FF"+getColor());
Mode mMode = Mode.SRC_ATOP;
Drawable d = mCtx.getResources().getDrawable(R.drawable.image);
d.setColorFilter(COLOR2,mMode)

我使用一些 API 演示代码创建了一个演示 Activity ,用于在每种滤色器模式之间进行切换,以在不同情况下尝试它们,并发现它非常宝贵,所以我想我会在这里发布。

public class ColorFilters extends GraphicsActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(new SampleView(this));

}

private static class SampleView extends View {
private Activity mActivity;
private Drawable mDrawable;
private Drawable[] mDrawables;
private Paint mPaint;
private Paint mPaint2;
private float mPaintTextOffset;
private int[] mColors;
private PorterDuff.Mode[] mModes;
private int mModeIndex;
private Typeface futura_bold;
private AssetManager assets;

private static void addToTheRight(Drawable curr, Drawable prev) {
Rect r = prev.getBounds();
int x = r.right + 12;
int center = (r.top + r.bottom) >> 1;
int h = curr.getIntrinsicHeight();
int y = center - (h >> 1);

curr.setBounds(x, y, x + curr.getIntrinsicWidth(), y + h);
}

public SampleView(Activity activity) {
super(activity);
mActivity = activity;
Context context = activity;
setFocusable(true);

/**1. GET DRAWABLE, SET BOUNDS */
assets = context.getAssets();
mDrawable = context.getResources().getDrawable(R.drawable.roundrect_gray_button_bg_nine);
mDrawable.setBounds(0, 0, mDrawable.getIntrinsicWidth(), mDrawable.getIntrinsicHeight());

mDrawable.setDither(true);

int[] resIDs = new int[] {
R.drawable.roundrect_gray_button_bg,
R.drawable.order_button_white,
R.drawable.yellowbar
};
mDrawables = new Drawable[resIDs.length];
Drawable prev = mDrawable;
for (int i = 0; i < resIDs.length; i++) {
mDrawables[i] = context.getResources().getDrawable(resIDs[i]);
mDrawables[i].setDither(true);
addToTheRight(mDrawables[i], prev);
prev = mDrawables[i];
}

/**2. SET Paint for writing text on buttons */
mPaint = new Paint();
mPaint.setAntiAlias(true);
mPaint.setTextSize(16);
mPaint.setTextAlign(Paint.Align.CENTER);

mPaint2 = new Paint(mPaint);
/** Calculating size based on font */
futura_bold = Typeface.createFromAsset(assets,
"fonts/futurastd-bold.otf");
//Determine size and offset to write text in label based on font size.
mPaint.setTypeface(futura_bold);
Paint.FontMetrics fm = mPaint.getFontMetrics();
mPaintTextOffset = (fm.descent + fm.ascent) * 0.5f;

mColors = new int[] {
0,
0xFFA60017,//WE USE THESE
0xFFC6D405,
0xFF4B5B98,
0xFF656565,
0xFF8888FF,
0xFF4444FF,
};

mModes = new PorterDuff.Mode[] {
PorterDuff.Mode.DARKEN,
PorterDuff.Mode.DST,
PorterDuff.Mode.DST_ATOP,
PorterDuff.Mode.DST_IN,
PorterDuff.Mode.DST_OUT,
PorterDuff.Mode.DST_OVER,
PorterDuff.Mode.LIGHTEN,
PorterDuff.Mode.MULTIPLY,
PorterDuff.Mode.SCREEN,
PorterDuff.Mode.SRC,
PorterDuff.Mode.SRC_ATOP,
PorterDuff.Mode.SRC_IN,
PorterDuff.Mode.SRC_OUT,
PorterDuff.Mode.SRC_OVER,
PorterDuff.Mode.XOR
};
mModeIndex = 0;

updateTitle();
}

private void swapPaintColors() {
if (mPaint.getColor() == 0xFF000000) {
mPaint.setColor(0xFFFFFFFF);
mPaint2.setColor(0xFF000000);
} else {
mPaint.setColor(0xFF000000);
mPaint2.setColor(0xFFFFFFFF);
}
mPaint2.setAlpha(0);
}

private void updateTitle() {
mActivity.setTitle(mModes[mModeIndex].toString());
}

private void drawSample(Canvas canvas, ColorFilter filter) {
/** Create a rect around bounds, ensure size offset */
Rect r = mDrawable.getBounds();
float x = (r.left + r.right) * 0.5f;
float y = (r.top + r.bottom) * 0.5f - mPaintTextOffset;

/**Set color filter to selected color
* create canvas (filled with this color)
* Write text using paint (new color)
*/
mDrawable.setColorFilter(filter);
mDrawable.draw(canvas);
/** If the text doesn't fit in the button, make the text size smaller until it does*/
final float size = mPaint.measureText("Label");
if((int) size > (r.right-r.left)) {
float ts = mPaint.getTextSize();
Log.w("DEBUG","Text size was"+ts);
mPaint.setTextSize(ts-2);
}
canvas.drawText("Sausage Burrito", x, y, mPaint);
/** Write the text and draw it onto the drawable*/

for (Drawable dr : mDrawables) {
dr.setColorFilter(filter);
dr.draw(canvas);
}
}

@Override protected void onDraw(Canvas canvas) {
canvas.drawColor(0xFFCCCCCC);

canvas.translate(8, 12);
for (int color : mColors) {
ColorFilter filter;
if (color == 0) {
filter = null;
} else {
filter = new PorterDuffColorFilter(color,
mModes[mModeIndex]);
}
drawSample(canvas, filter);
canvas.translate(0, 55);
}
}

@Override
public boolean onTouchEvent(MotionEvent event) {
float x = event.getX();
float y = event.getY();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
break;
case MotionEvent.ACTION_MOVE:
break;
case MotionEvent.ACTION_UP:
// update mode every other time we change paint colors
if (mPaint.getColor() == 0xFFFFFFFF) {
mModeIndex = (mModeIndex + 1) % mModes.length;
updateTitle();
}
swapPaintColors();
invalidate();
break;
}
return true;
}
}
}

另外两个依赖项,GraphicsActivity.java 和 PictureLayout.java,如果您想测试一下,可以直接从 API Demos Activity 中复制。

关于android - 修改 android drawable 的颜色,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9643603/

38 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com