我在一个android应用程序上工作,我有一个可绘制的,我正在从源图像加载。在这个图像上,我想将所有的白色像素转换为不同的颜色,比如蓝色,然后缓存生成的Drawable对象,以便以后使用它。
例如,我有一个20x20的PNG文件,中间有一个白色的圆圈,圆圈之外的一切都是透明的。把白色圆圈变成蓝色并缓存结果的最好方法是什么?如果我想使用源图像来创建几个新的Drawables(比如蓝色、红色、绿色、橙色等),答案会改变吗?
我猜我想在某种程度上使用一个ColorMatrix,但我不确定如何。
我在一个android应用程序上工作,我有一个可绘制的,我正在从源图像加载。在这个图像上,我想将所有的白色像素转换为不同的颜色,比如蓝色,然后缓存生成的Drawable对象,以便以后使用它。
例如,我有一个20x20的PNG文件,中间有一个白色的圆圈,圆圈之外的一切都是透明的。把白色圆圈变成蓝色并缓存结果的最好方法是什么?如果我想使用源图像来创建几个新的Drawables(比如蓝色、红色、绿色、橙色等),答案会改变吗?
我猜我想在某种程度上使用一个ColorMatrix,但我不确定如何。
当前回答
我只是遇到了这个问题,并通过替换来解决它:
android:tint="@color/yellow_800"
到以下
app:tint="@color/yellow_800"
其他回答
查看这个示例代码"ColorMatrixSample.java"
/*
* Copyright (C) 2007 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.example.android.apis.graphics;
import com.example.android.apis.R;
import android.app.Activity;
import android.content.Context;
import android.graphics.*;
import android.os.Bundle;
import android.view.KeyEvent;
import android.view.View;
public class ColorMatrixSample extends GraphicsActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(new SampleView(this));
}
private static class SampleView extends View {
private Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
private ColorMatrix mCM = new ColorMatrix();
private Bitmap mBitmap;
private float mSaturation;
private float mAngle;
public SampleView(Context context) {
super(context);
mBitmap = BitmapFactory.decodeResource(context.getResources(),
R.drawable.balloons);
}
private static void setTranslate(ColorMatrix cm, float dr, float dg,
float db, float da) {
cm.set(new float[] {
2, 0, 0, 0, dr,
0, 2, 0, 0, dg,
0, 0, 2, 0, db,
0, 0, 0, 1, da });
}
private static void setContrast(ColorMatrix cm, float contrast) {
float scale = contrast + 1.f;
float translate = (-.5f * scale + .5f) * 255.f;
cm.set(new float[] {
scale, 0, 0, 0, translate,
0, scale, 0, 0, translate,
0, 0, scale, 0, translate,
0, 0, 0, 1, 0 });
}
private static void setContrastTranslateOnly(ColorMatrix cm, float contrast) {
float scale = contrast + 1.f;
float translate = (-.5f * scale + .5f) * 255.f;
cm.set(new float[] {
1, 0, 0, 0, translate,
0, 1, 0, 0, translate,
0, 0, 1, 0, translate,
0, 0, 0, 1, 0 });
}
private static void setContrastScaleOnly(ColorMatrix cm, float contrast) {
float scale = contrast + 1.f;
float translate = (-.5f * scale + .5f) * 255.f;
cm.set(new float[] {
scale, 0, 0, 0, 0,
0, scale, 0, 0, 0,
0, 0, scale, 0, 0,
0, 0, 0, 1, 0 });
}
@Override protected void onDraw(Canvas canvas) {
Paint paint = mPaint;
float x = 20;
float y = 20;
canvas.drawColor(Color.WHITE);
paint.setColorFilter(null);
canvas.drawBitmap(mBitmap, x, y, paint);
ColorMatrix cm = new ColorMatrix();
mAngle += 2;
if (mAngle > 180) {
mAngle = 0;
}
//convert our animated angle [-180...180] to a contrast value of [-1..1]
float contrast = mAngle / 180.f;
setContrast(cm, contrast);
paint.setColorFilter(new ColorMatrixColorFilter(cm));
canvas.drawBitmap(mBitmap, x + mBitmap.getWidth() + 10, y, paint);
setContrastScaleOnly(cm, contrast);
paint.setColorFilter(new ColorMatrixColorFilter(cm));
canvas.drawBitmap(mBitmap, x, y + mBitmap.getHeight() + 10, paint);
setContrastTranslateOnly(cm, contrast);
paint.setColorFilter(new ColorMatrixColorFilter(cm));
canvas.drawBitmap(mBitmap, x, y + 2*(mBitmap.getHeight() + 10),
paint);
invalidate();
}
}
}
有关的API可在此下载:
我可以用下面的代码做到这一点,这是从一个活动(布局是一个非常简单的,只包含一个ImageView,并没有张贴在这里)。
private static final int[] FROM_COLOR = new int[]{49, 179, 110};
private static final int THRESHOLD = 3;
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.test_colors);
ImageView iv = (ImageView) findViewById(R.id.img);
Drawable d = getResources().getDrawable(RES);
iv.setImageDrawable(adjust(d));
}
private Drawable adjust(Drawable d)
{
int to = Color.RED;
//Need to copy to ensure that the bitmap is mutable.
Bitmap src = ((BitmapDrawable) d).getBitmap();
Bitmap bitmap = src.copy(Bitmap.Config.ARGB_8888, true);
for(int x = 0;x < bitmap.getWidth();x++)
for(int y = 0;y < bitmap.getHeight();y++)
if(match(bitmap.getPixel(x, y)))
bitmap.setPixel(x, y, to);
return new BitmapDrawable(bitmap);
}
private boolean match(int pixel)
{
//There may be a better way to match, but I wanted to do a comparison ignoring
//transparency, so I couldn't just do a direct integer compare.
return Math.abs(Color.red(pixel) - FROM_COLOR[0]) < THRESHOLD &&
Math.abs(Color.green(pixel) - FROM_COLOR[1]) < THRESHOLD &&
Math.abs(Color.blue(pixel) - FROM_COLOR[2]) < THRESHOLD;
}
Koltin解决方案使用视图绑定:
binding.avatar.drawable.colorFilter = BlendModeColorFilterCompat.createBlendModeColorFilterCompat(R.color.white, BlendModeCompat.SRC_ATOP)
这使用了最新版本的核心androidx库。
有这么多的解决方案,但没有人建议,如果颜色资源xml文件已经有颜色,那么我们可以直接从那里也如下所示:
ImageView imageView = (ImageView) findViewById(R.id.imageview);
imageView.setColorFilter(getString(R.color.your_color));
我认为你可以使用Drawable。setColorFilter(0xffff0000,模式。用)。这将把白色像素设置为红色,但我不认为它会影响透明像素。
看到可拉的# setColorFilter