Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
We don’t allow questions seeking recommendations for books, tools, software libraries, and more. You can edit the question so it can be answered with facts and citations.
Closed 5 years ago.
Improve this question
I am looking for a Color Picker framework which can return color HEX on selection.
I have looked at this wondering if there is some other library I can use.
I know the question is old, but if someone is looking for a great new android color picker that use material design I have forked an great project from github and made a simple-to-use android color picker dialog.
This is the project: Android Color Picker
Android Color Picker dialog
HOW TO USE IT
Adding the library to your project
The aar artifact is available at the jcenter repository. Declare the repository and the
dependency in your build.gradle.
(root)
repositories {
jcenter()
}
(module)
dependencies {
compile 'com.pes.materialcolorpicker:library:1.0.2'
}
Use the library
Create a color picker dialog object
final ColorPicker cp = new ColorPicker(MainActivity.this, defaultColorR, defaultColorG, defaultColorB);
defaultColorR, defaultColorG, defaultColorB are 3 integer ( value 0-255) for the initialization of the color picker with your custom color value. If you don't want to start with a color set them to 0 or use only the first argument
Then show the dialog (when & where you want) and save the selected color
/* Show color picker dialog */
cp.show();
/* On Click listener for the dialog, when the user select the color */
Button okColor = (Button)cp.findViewById(R.id.okColorButton);
okColor.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
/* You can get single channel (value 0-255) */
selectedColorR = cp.getRed();
selectedColorG = cp.getGreen();
selectedColorB = cp.getBlue();
/* Or the android RGB Color (see the android Color class reference) */
selectedColorRGB = cp.getColor();
cp.dismiss();
}
});
That's all :)
try this open source projects that might help you
https://github.com/QuadFlask/colorpicker
You can use the following code, it will give you same look as http://code.google.com/p/color-picker-view/
public class ColorPickerDialog extends Dialog {
public interface OnColorChangedListener {
void colorChanged(String key, int color);
}
private OnColorChangedListener mListener;
private int mInitialColor, mDefaultColor;
private String mKey;
private static class ColorPickerView extends View {
private Paint mPaint;
private float mCurrentHue = 0;
private int mCurrentX = 0, mCurrentY = 0;
private int mCurrentColor, mDefaultColor;
private final int[] mHueBarColors = new int[258];
private int[] mMainColors = new int[65536];
private OnColorChangedListener mListener;
ColorPickerView(Context c, OnColorChangedListener l, int color,
int defaultColor) {
super(c);
mListener = l;
mDefaultColor = defaultColor;
// Get the current hue from the current color and update the main
// color field
float[] hsv = new float[3];
Color.colorToHSV(color, hsv);
mCurrentHue = hsv[0];
updateMainColors();
mCurrentColor = color;
// Initialize the colors of the hue slider bar
int index = 0;
for (float i = 0; i < 256; i += 256 / 42) // Red (#f00) to pink
// (#f0f)
{
mHueBarColors[index] = Color.rgb(255, 0, (int) i);
index++;
}
for (float i = 0; i < 256; i += 256 / 42) // Pink (#f0f) to blue
// (#00f)
{
mHueBarColors[index] = Color.rgb(255 - (int) i, 0, 255);
index++;
}
for (float i = 0; i < 256; i += 256 / 42) // Blue (#00f) to light
// blue (#0ff)
{
mHueBarColors[index] = Color.rgb(0, (int) i, 255);
index++;
}
for (float i = 0; i < 256; i += 256 / 42) // Light blue (#0ff) to
// green (#0f0)
{
mHueBarColors[index] = Color.rgb(0, 255, 255 - (int) i);
index++;
}
for (float i = 0; i < 256; i += 256 / 42) // Green (#0f0) to yellow
// (#ff0)
{
mHueBarColors[index] = Color.rgb((int) i, 255, 0);
index++;
}
for (float i = 0; i < 256; i += 256 / 42) // Yellow (#ff0) to red
// (#f00)
{
mHueBarColors[index] = Color.rgb(255, 255 - (int) i, 0);
index++;
}
// Initializes the Paint that will draw the View
mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mPaint.setTextAlign(Paint.Align.CENTER);
mPaint.setTextSize(12);
}
// Get the current selected color from the hue bar
private int getCurrentMainColor() {
int translatedHue = 255 - (int) (mCurrentHue * 255 / 360);
int index = 0;
for (float i = 0; i < 256; i += 256 / 42) {
if (index == translatedHue)
return Color.rgb(255, 0, (int) i);
index++;
}
for (float i = 0; i < 256; i += 256 / 42) {
if (index == translatedHue)
return Color.rgb(255 - (int) i, 0, 255);
index++;
}
for (float i = 0; i < 256; i += 256 / 42) {
if (index == translatedHue)
return Color.rgb(0, (int) i, 255);
index++;
}
for (float i = 0; i < 256; i += 256 / 42) {
if (index == translatedHue)
return Color.rgb(0, 255, 255 - (int) i);
index++;
}
for (float i = 0; i < 256; i += 256 / 42) {
if (index == translatedHue)
return Color.rgb((int) i, 255, 0);
index++;
}
for (float i = 0; i < 256; i += 256 / 42) {
if (index == translatedHue)
return Color.rgb(255, 255 - (int) i, 0);
index++;
}
return Color.RED;
}
// Update the main field colors depending on the current selected hue
private void updateMainColors() {
int mainColor = getCurrentMainColor();
int index = 0;
int[] topColors = new int[256];
for (int y = 0; y < 256; y++) {
for (int x = 0; x < 256; x++) {
if (y == 0) {
mMainColors[index] = Color.rgb(
255 - (255 - Color.red(mainColor)) * x / 255,
255 - (255 - Color.green(mainColor)) * x / 255,
255 - (255 - Color.blue(mainColor)) * x / 255);
topColors[x] = mMainColors[index];
} else
mMainColors[index] = Color.rgb(
(255 - y) * Color.red(topColors[x]) / 255,
(255 - y) * Color.green(topColors[x]) / 255,
(255 - y) * Color.blue(topColors[x]) / 255);
index++;
}
}
}
#Override
protected void onDraw(Canvas canvas) {
int translatedHue = 255 - (int) (mCurrentHue * 255 / 360);
// Display all the colors of the hue bar with lines
for (int x = 0; x < 256; x++) {
// If this is not the current selected hue, display the actual
// color
if (translatedHue != x) {
mPaint.setColor(mHueBarColors[x]);
mPaint.setStrokeWidth(1);
} else // else display a slightly larger black line
{
mPaint.setColor(Color.BLACK);
mPaint.setStrokeWidth(3);
}
canvas.drawLine(x + 10, 0, x + 10, 40, mPaint);
// canvas.drawLine(0, x+10, 40, x+10, mPaint);
}
// Display the main field colors using LinearGradient
for (int x = 0; x < 256; x++) {
int[] colors = new int[2];
colors[0] = mMainColors[x];
colors[1] = Color.BLACK;
Shader shader = new LinearGradient(0, 50, 0, 306, colors, null,
Shader.TileMode.REPEAT);
mPaint.setShader(shader);
canvas.drawLine(x + 10, 50, x + 10, 306, mPaint);
}
mPaint.setShader(null);
// Display the circle around the currently selected color in the
// main field
if (mCurrentX != 0 && mCurrentY != 0) {
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setColor(Color.BLACK);
canvas.drawCircle(mCurrentX, mCurrentY, 10, mPaint);
}
// Draw a 'button' with the currently selected color
mPaint.setStyle(Paint.Style.FILL);
mPaint.setColor(mCurrentColor);
canvas.drawRect(10, 316, 138, 356, mPaint);
// Set the text color according to the brightness of the color
if (Color.red(mCurrentColor) + Color.green(mCurrentColor)
+ Color.blue(mCurrentColor) < 384)
mPaint.setColor(Color.WHITE);
else
mPaint.setColor(Color.BLACK);
canvas.drawText(
getResources()
.getString(R.string.settings_bg_color_confirm), 74,
340, mPaint);
// Draw a 'button' with the default color
mPaint.setStyle(Paint.Style.FILL);
mPaint.setColor(mDefaultColor);
canvas.drawRect(138, 316, 266, 356, mPaint);
// Set the text color according to the brightness of the color
if (Color.red(mDefaultColor) + Color.green(mDefaultColor)
+ Color.blue(mDefaultColor) < 384)
mPaint.setColor(Color.WHITE);
else
mPaint.setColor(Color.BLACK);
canvas.drawText(
getResources().getString(
R.string.settings_default_color_confirm), 202, 340,
mPaint);
}
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
setMeasuredDimension(276, 366);
}
#Override
public boolean onTouchEvent(MotionEvent event) {
if (event.getAction() != MotionEvent.ACTION_DOWN)
return true;
float x = event.getX();
float y = event.getY();
// If the touch event is located in the hue bar
if (x > 10 && x < 266 && y > 0 && y < 40) {
// Update the main field colors
mCurrentHue = (255 - x) * 360 / 255;
updateMainColors();
// Update the current selected color
int transX = mCurrentX - 10;
int transY = mCurrentY - 60;
int index = 256 * (transY - 1) + transX;
if (index > 0 && index < mMainColors.length)
mCurrentColor = mMainColors[256 * (transY - 1) + transX];
// Force the redraw of the dialog
invalidate();
}
// If the touch event is located in the main field
if (x > 10 && x < 266 && y > 50 && y < 306) {
mCurrentX = (int) x;
mCurrentY = (int) y;
int transX = mCurrentX - 10;
int transY = mCurrentY - 60;
int index = 256 * (transY - 1) + transX;
if (index > 0 && index < mMainColors.length) {
// Update the current color
mCurrentColor = mMainColors[index];
// Force the redraw of the dialog
invalidate();
}
}
// If the touch event is located in the left button, notify the
// listener with the current color
if (x > 10 && x < 138 && y > 316 && y < 356)
mListener.colorChanged("", mCurrentColor);
// If the touch event is located in the right button, notify the
// listener with the default color
if (x > 138 && x < 266 && y > 316 && y < 356)
mListener.colorChanged("", mDefaultColor);
return true;
}
}
public ColorPickerDialog(Context context, OnColorChangedListener listener,
String key, int initialColor, int defaultColor) {
super(context);
mListener = listener;
mKey = key;
mInitialColor = initialColor;
mDefaultColor = defaultColor;
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
OnColorChangedListener l = new OnColorChangedListener() {
public void colorChanged(String key, int color) {
mListener.colorChanged(mKey, color);
dismiss();
}
};
setContentView(new ColorPickerView(getContext(), l, mInitialColor,
mDefaultColor));
setTitle(R.string.settings_bg_color_dialog);
}
}
I ended up here looking for a HSV color picker that offered transparency and copy/paste of the hex value. None of the existing answers met those needs, so here's the library I ended up writing:
HSV-Alpha Color Picker for Android (GitHub).
HSV-Alpha Color Picker Demo (Google Play).
I hope it's useful for somebody else.
We have just uploaded AmbilWarna color picker to Maven:
https://github.com/yukuku/ambilwarna
It can be used either as a dialog or as a Preference entry.
If you want a fragment solution, I have made a fork of android-color-picker where DialogFragment is used and is re-created on configuration change. Here's the link: https://github.com/lomza/android-color-picker
Here's another library:
https://github.com/eltos/SimpleDialogFragments
Features color wheel and pallet picker dialogs
Usage for HSV Color picker:
Add the library from maven and in your code just call:
SimpleColorWheelDialog.build()
.color(0xFFCF4747) // optional initial color
.alpha(true)
.show(Activity.this, COLOR_PICKER);
and to get the results let the Activity or fragment implement OnDialogResultListener:
#Override
public boolean onResult(#NonNull String dialogTag, int which, #NonNull Bundle extras) {
if (COLOR_PICKER.equals(dialogTag) && which == BUTTON_POSITIVE){
int color = extras.getInt(SimpleColorWheelDialog.COLOR);
// ...
return true;
}
return false;
}
After some searches in the android references, the newcomer QuadFlask Color Picker seems to be a technically and aesthetically good choice. Also it has Transparency slider and supports HEX coded colors.
Take a look:
QuadFlask Color Picker
Related
I am using MPAndroidChart library and my requirement is to show stack value in stack color as given in picture and also not above the bar but left and right for the alternate stack.
I have tried like this way but it didn't work
set.setValueTextColors(colorList);
It's giving one color for one complete bar.
I used a custom renderer to fix the issue
Here is the code
Chart creation
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_mp_android_stacked_bar_chart);
barChart = (BarChart) this.findViewById(R.id.bar_chart);
float[] val1 = {10, 20, 30, 40, 50, 60, 70};
float[] val2 = {70, 60, 50, 40, 30, 20, 10};
ArrayList<BarEntry> yVals1 = new ArrayList<BarEntry>();
for (int i = 0; i < val1.length; i++) {
yVals1.add(new BarEntry(i, new float[]{val1[i], val2[i]}));
}
barChart.getDescription().setEnabled(false);
barChart.setPinchZoom(false); // scaling can now only be done on x- and y-axis separately
barChart.setDrawGridBackground(false);
barChart.setDrawBarShadow(false);
barChart.setDrawValueAboveBar(true);
barChart.setHighlightFullBarEnabled(false);
barChart.getAxisRight().setEnabled(false);
YAxis yAxis = barChart.getAxisLeft(); // change the position of the y-labels
yAxis.setAxisMinimum(0f);
yAxis.setDrawGridLines(false);
XAxis xAxis = barChart.getXAxis();
xAxis.setPosition(XAxis.XAxisPosition.BOTTOM);
xAxis.setGranularity(1f);
xAxis.setDrawGridLines(false);
ArrayList<Integer> colorList = new ArrayList<>();
colorList.add(ContextCompat.getColor(this, R.color.colorPrimaryDark));
colorList.add(ContextCompat.getColor(this, R.color.colorAccent));
barChart.getLegend().setEnabled(false);
barChart.setRenderer(new StackedBarChartRenderer(barChart, barChart.getAnimator(), barChart.getViewPortHandler(), colorList));
BarDataSet set1 = new BarDataSet(yVals1, "");
set1.setColors(colorList);
ArrayList<IBarDataSet> dataSets = new ArrayList<>();
dataSets.add(set1);
BarData data = new BarData(dataSets);
barChart.setData(data);
barChart.setVisibleXRangeMaximum(4f);
barChart.invalidate();
}
These are important lines in the above code. Here we are setting the our own renderer class for the graph where we pass the required colorList
ArrayList<Integer> colorList = new ArrayList<>();
colorList.add(ContextCompat.getColor(this, R.color.colorPrimaryDark));
colorList.add(ContextCompat.getColor(this, R.color.colorAccent));
barChart.setRenderer(new StackedBarChartRenderer(barChart, barChart.getAnimator(), barChart.getViewPortHandler(), colorList));
RENDERER
public class StackedBarChartRenderer extends BarChartRenderer {
private ArrayList<Integer> colorList;
private int index = 0;
private int numOfColors;
public StackedBarChartRenderer(BarDataProvider chart, ChartAnimator animator, ViewPortHandler viewPortHandler, ArrayList<Integer> colorList) {
super(chart, animator, viewPortHandler);
this.colorList = colorList;
this.numOfColors = colorList.size();
}
public void drawValue(Canvas c, IValueFormatter formatter, float value, Entry entry, int dataSetIndex, float x, float y, int color) {
mValuePaint.setColor(colorList.get(index));
if(value != 0){
c.drawText(formatter.getFormattedValue(value, entry, dataSetIndex, mViewPortHandler), x, y, mValuePaint);
}
index = ((index + 1) % (numOfColors));
}
}
In the above code we are overriding the necessary methods and iterating through the colorList in a cicular manner. You may have to change the logic
of the drawValue() function to suit your requirements.
To know more about how custom renderer works, check this link
Result
EDIT
#Override
public void drawValues(Canvas c) {
// if values are drawn
if (isDrawingValuesAllowed(mChart)) {
List<IBarDataSet> dataSets = mChart.getBarData().getDataSets();
final float valueOffsetPlus = Utils.convertDpToPixel(4.5f);
float posOffset = 0f;
float negOffset = 0f;
boolean drawValueAboveBar = mChart.isDrawValueAboveBarEnabled();
for (int i = 0; i < mChart.getBarData().getDataSetCount(); i++) {
IBarDataSet dataSet = dataSets.get(i);
if (!shouldDrawValues(dataSet))
continue;
// apply the text-styling defined by the DataSet
applyValueTextStyle(dataSet);
boolean isInverted = mChart.isInverted(dataSet.getAxisDependency());
// calculate the correct offset depending on the draw position of
// the value
float valueTextHeight = Utils.calcTextHeight(mValuePaint, "8");
posOffset = (drawValueAboveBar ? -valueOffsetPlus : valueTextHeight + valueOffsetPlus);
negOffset = (drawValueAboveBar ? valueTextHeight + valueOffsetPlus : -valueOffsetPlus);
if (isInverted) {
posOffset = -posOffset - valueTextHeight;
negOffset = -negOffset - valueTextHeight;
}
// get the buffer
BarBuffer buffer = mBarBuffers[i];
final float phaseY = mAnimator.getPhaseY();
MPPointF iconsOffset = MPPointF.getInstance(dataSet.getIconsOffset());
iconsOffset.x = Utils.convertDpToPixel(iconsOffset.x);
iconsOffset.y = Utils.convertDpToPixel(iconsOffset.y);
// if only single values are drawn (sum)
if (!dataSet.isStacked()) {
for (int j = 0; j < buffer.buffer.length * mAnimator.getPhaseX(); j += 4) {
float x = (buffer.buffer[j] + buffer.buffer[j + 2]) / 2f;
if (!mViewPortHandler.isInBoundsRight(x))
break;
if (!mViewPortHandler.isInBoundsY(buffer.buffer[j + 1])
|| !mViewPortHandler.isInBoundsLeft(x))
continue;
BarEntry entry = dataSet.getEntryForIndex(j / 4);
float val = entry.getY();
if (dataSet.isDrawValuesEnabled()) {
drawValue(c, dataSet.getValueFormatter(), val, entry, i, x,
val >= 0 ?
(buffer.buffer[j + 1] + posOffset) :
(buffer.buffer[j + 3] + negOffset),
dataSet.getValueTextColor(j / 4));
}
if (entry.getIcon() != null && dataSet.isDrawIconsEnabled()) {
Drawable icon = entry.getIcon();
float px = x;
float py = val >= 0 ?
(buffer.buffer[j + 1] + posOffset) :
(buffer.buffer[j + 3] + negOffset);
px += iconsOffset.x;
py += iconsOffset.y;
Utils.drawImage(
c,
icon,
(int)px,
(int)py,
icon.getIntrinsicWidth(),
icon.getIntrinsicHeight());
}
}
// if we have stacks
} else {
Transformer trans = mChart.getTransformer(dataSet.getAxisDependency());
int bufferIndex = 0;
int index = 0;
while (index < dataSet.getEntryCount() * mAnimator.getPhaseX()) {
BarEntry entry = dataSet.getEntryForIndex(index);
float[] vals = entry.getYVals();
float x = (buffer.buffer[bufferIndex] + buffer.buffer[bufferIndex + 2]) / 2f;
int color = dataSet.getValueTextColor(index);
// we still draw stacked bars, but there is one
// non-stacked
// in between
if (vals == null) {
if (!mViewPortHandler.isInBoundsRight(x))
break;
if (!mViewPortHandler.isInBoundsY(buffer.buffer[bufferIndex + 1])
|| !mViewPortHandler.isInBoundsLeft(x))
continue;
if (dataSet.isDrawValuesEnabled()) {
drawValue(c, dataSet.getValueFormatter(), entry.getY(), entry, i, x,
buffer.buffer[bufferIndex + 1] +
(entry.getY() >= 0 ? posOffset : negOffset),
color);
}
if (entry.getIcon() != null && dataSet.isDrawIconsEnabled()) {
Drawable icon = entry.getIcon();
float px = x;
float py = buffer.buffer[bufferIndex + 1] +
(entry.getY() >= 0 ? posOffset : negOffset);
px += iconsOffset.x;
py += iconsOffset.y;
Utils.drawImage(
c,
icon,
(int)px,
(int)py,
icon.getIntrinsicWidth(),
icon.getIntrinsicHeight());
}
// draw stack values
} else {
float[] transformed = new float[vals.length * 2];
float posY = 0f;
float negY = -entry.getNegativeSum();
for (int k = 0, idx = 0; k < transformed.length; k += 2, idx++) {
float value = vals[idx];
float y;
if (value == 0.0f && (posY == 0.0f || negY == 0.0f)) {
// Take care of the situation of a 0.0 value, which overlaps a non-zero bar
y = value;
} else if (value >= 0.0f) {
posY += value;
y = posY;
} else {
y = negY;
negY -= value;
}
transformed[k + 1] = y * phaseY;
}
trans.pointValuesToPixel(transformed);
for (int k = 0; k < transformed.length; k += 2) {
final float val = vals[k / 2];
final boolean drawBelow =
(val == 0.0f && negY == 0.0f && posY > 0.0f) ||
val < 0.0f;
float y = transformed[k + 1]
+ (drawBelow ? negOffset : posOffset);
if (!mViewPortHandler.isInBoundsRight(x))
break;
if(val == 0){
drawValue(c,
dataSet.getValueFormatter(),
vals[k / 2],
entry,
i,
x,
y,
color);
}
if (!mViewPortHandler.isInBoundsY(y)
|| !mViewPortHandler.isInBoundsLeft(x))
continue;
if (dataSet.isDrawValuesEnabled()) {
drawValue(c,
dataSet.getValueFormatter(),
vals[k / 2],
entry,
i,
x,
y,
color);
}
if (entry.getIcon() != null && dataSet.isDrawIconsEnabled()) {
Drawable icon = entry.getIcon();
Utils.drawImage(
c,
icon,
(int)(x + iconsOffset.x),
(int)(y + iconsOffset.y),
icon.getIntrinsicWidth(),
icon.getIntrinsicHeight());
}
}
}
bufferIndex = vals == null ? bufferIndex + 4 : bufferIndex + 4 * vals.length;
index++;
}
}
MPPointF.recycleInstance(iconsOffset);
}
}
}
Add this function to your custom render pick up the proper color even if some of your values are 0 in the stacked graph. This above function is exactly same as the default implementation expect for the following part :
if(val == 0){
drawValue(c,
dataSet.getValueFormatter(),
vals[k / 2],
entry,
i,
x,
y,
color);
}
I am trying to implement a seek bar to change contrast of an image in android. Anyone Help me to Implement this please.There is any other options for image processing ?
Does anyone know the solution Please help me
Thanks in Advance.
CODE:
public class MainActivity extends ActionBarActivity {
ImageView imViewAndroid;
private SeekBar seekbar;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
seekbar = (SeekBar) findViewById(R.id.seekbar);
imViewAndroid = (ImageView) findViewById(R.id.imViewAndroid);
seekbar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
#Override
public void onProgressChanged(SeekBar seekBar, int i, boolean b) {
}
#Override
public void onStartTrackingTouch(SeekBar seekBar) {
imViewAndroid.setImageBitmap(takeContrast(BitmapFactory.decodeResource(getResources(), R.drawable.dicom), 100));
}
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
});
}
public Bitmap takeContrast(Bitmap src, double value) {
// src image size
int width = src.getWidth();
int height = src.getHeight();
// create output bitmap with original size
Bitmap bmOut = Bitmap.createBitmap(width, height, src.getConfig());
// color information
int A, R, G, B;
int pixel;
// get contrast value
double contrast = Math.pow((100 + value) / 100, 2);
// scan through all pixels
for(int x = 0; x < width; ++x) {
for(int y = 0; y < height; ++y) {
// get pixel color
pixel = src.getPixel(x, y);
A = Color.alpha(pixel);
// apply filter contrast for every channel R, G, B
R = Color.red(pixel);
R = (int)(((((R / 255.0) - 0.5) * contrast) + 0.5) * 255.0);
if(R < 0) { R = 0; }
else if(R > 255) { R = 255; }
G = Color.red(pixel);
G = (int)(((((G / 255.0) - 0.5) * contrast) + 0.5) * 255.0);
if(G < 0) { G = 0; }
else if(G > 255) { G = 255; }
B = Color.red(pixel);
B = (int)(((((B / 255.0) - 0.5) * contrast) + 0.5) * 255.0);
if(B < 0) { B = 0; }
else if(B > 255) { B = 255; }
// set new pixel color to output bitmap
bmOut.setPixel(x, y, Color.argb(A, R, G, B));
}
}
// return final image
return bmOut;
}
You call the function to change contrast in a wrong place it should be here
#Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean b) {
// call the method here, default progress is <0, 100>
}
You use very slow function to change the contrast. There are plenty answers already on StackOverflow, have a look at this answer. Search before you ask.
Look at this full implementation on my github.
The above code takes too much time for processing image. If you use my code processing of image takes very less time.
#Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean b) {
contrastAndBrightnessControler(bitmap,seekbar.getProgress()/10,0.7)
}
public static Bitmap contrastAndBrightnessControler(Bitmap bitmap, float contrast, float brightness)
{
ColorMatrix cmatrix = new ColorMatrix(new float[]
{
contrast, 0, 0, 0, brightness,
0, contrast, 0, 0, brightness,
0, 0, contrast, 0, brightness,
0, 0, 0, 1, 0
});
Bitmap ret =Bitmap.createBitmap(bitmap.getWidth(),bitmap.getHeight(), bitmap.getConfig());
Canvas canvas = new Canvas(ret);
Paint paint = new Paint();
paint.setColorFilter(new ColorMatrixColorFilter(cmatrix));
canvas.drawBitmap(bitmap, 0, 0, paint);
return ret;
}
I want to use this color pikcerdialog https://code.google.com/p/android-color-picker/ but i have no idea what to do. I've added external jars and stuff before but this is different when you download it you get a project. I'm not to new to android but am still relatively new. Is that whole project the library or something. I really don't know where to begin but would really like help. even a link to a tutorial would be nice because i dont know what to search.
package com.example.color;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.SharedPreferences;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager.NameNotFoundException;
import android.preference.PreferenceManager;
import android.text.Html;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
public class AboutDialog extends AlertDialog {
private ImageView mIconView;
private TextView mAppNameText;
private TextView mAboutText;
private TextView mVersionText;
public AboutDialog(Context context) {
super(context);
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View layout = inflater.inflate(R.layout.dialog, null);
mAboutText = (TextView) layout.findViewById(android.R.id.text2);
mVersionText = (TextView) layout.findViewById(android.R.id.text1);
mAppNameText = (TextView) layout.findViewById(android.R.id.title);
mIconView = (ImageView) layout.findViewById(android.R.id.icon);
setView(layout);
loadAbout();
setTitle("About");
mIconView.setOnClickListener(new View.OnClickListener() {
int mClickCount = 0;
#Override
public void onClick(View v) {
mClickCount++;
if(mClickCount == 5) {
Toast.makeText(getContext(), "Upgraded to Pro Version!", Toast.LENGTH_SHORT).show();
new Thread(new Runnable() {
#Override
public void run() {
SharedPreferences.Editor edit = PreferenceManager.getDefaultSharedPreferences(getContext()).edit();
edit.putBoolean("is_pro", true);
edit.commit();
}
}).start();
}
}
});
setButton(DialogInterface.BUTTON_POSITIVE, getContext().getString(android.R.string.ok), new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
});
}
private void loadAbout(){
PackageInfo pi = null;
try {
pi = getContext().getPackageManager().getPackageInfo(getContext().getPackageName(), 0);
} catch (NameNotFoundException e) {
e.printStackTrace();
}
mAppNameText.setText("ColorPickerView");
mVersionText.setText("Version" + " " + (pi != null ? pi.versionName : "null"));
String s = "<b>Developed By:</b><br>Daniel Nilsson<br>";
mAboutText.setText(Html.fromHtml(s));
}
}
That was the dialog and this is just a really simple activity where i call it from
package com.example.color;
import com.example.color.ColorPickerDialog.OnColorChangedListener;
import android.os.Bundle;
import android.app.Activity;
import android.graphics.Color;
import android.graphics.Paint;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
public class MainActivity extends Activity implements OnColorChangedListener, OnClickListener {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button b = (Button) findViewById(R.id.button10);
b.setOnClickListener(this);
}
#Override
public void colorChanged(String key, int color) {
// TODO Auto-generated method stub
// Paint l = Paint.setColor(color);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
#Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
ColorPickerDialog color = new ColorPickerDialog(this,this, "picker",Color.BLACK,Color.WHITE);
color.show();
}
}
your welcome to use this modify it to your needs
import android.app.Dialog;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.LinearGradient;
import android.graphics.Paint;
import android.graphics.Shader;
import android.os.Bundle;
import android.view.MotionEvent;
import android.view.View;
public class ColorPickerDialog extends Dialog {
public interface OnColorChangedListener {
void colorChanged(String key, int color);
}
private OnColorChangedListener mListener;
private int mInitialColor, mDefaultColor;
private String mKey;
private class ColorPickerView extends View {
private Paint mPaint;
private float mCurrentHue = 0;
private int mCurrentX = 0, mCurrentY = 0;
private int mCurrentColor, mDefaultColor;
private final int[] mHueBarColors = new int[258];
private int[] mMainColors = new int[65536];
private OnColorChangedListener mListener;
private int width,height;
ColorPickerView(Context c, OnColorChangedListener l, int color,
int defaultColor) {
super(c);
mListener = l;
mDefaultColor = defaultColor;
// Get the current hue from the current color and update the main
// color field
float[] hsv = new float[3];
Color.colorToHSV(color, hsv);
mCurrentHue = hsv[0];
updateMainColors();
mCurrentColor = color;
// Initialize the colors of the hue slider bar
int index = 0;
for (float i = 0; i < 256; i += 256 / 42) // Red (#f00) to pink
// (#f0f)
{
mHueBarColors[index] = Color.rgb(255, 0, (int) i);
index++;
}
for (float i = 0; i < 256; i += 256 / 42) // Pink (#f0f) to blue
// (#00f)
{
mHueBarColors[index] = Color.rgb(255 - (int) i, 0, 255);
index++;
}
for (float i = 0; i < 256; i += 256 / 42) // Blue (#00f) to light
// blue (#0ff)
{
mHueBarColors[index] = Color.rgb(0, (int) i, 255);
index++;
}
for (float i = 0; i < 256; i += 256 / 42) // Light blue (#0ff) to
// green (#0f0)
{
mHueBarColors[index] = Color.rgb(0, 255, 255 - (int) i);
index++;
}
for (float i = 0; i < 256; i += 256 / 42) // Green (#0f0) to yellow
// (#ff0)
{
mHueBarColors[index] = Color.rgb((int) i, 255, 0);
index++;
}
for (float i = 0; i < 256; i += 256 / 42) // Yellow (#ff0) to red
// (#f00)
{
mHueBarColors[index] = Color.rgb(255, 255 - (int) i, 0);
index++;
}
// Initializes the Paint that will draw the View
mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mPaint.setTextAlign(Paint.Align.CENTER);
mPaint.setTextSize(12);
}
// Get the current selected color from the hue bar
private int getCurrentMainColor() {
int translatedHue = 255 - (int) (mCurrentHue * 255 / 360);
int index = 0;
for (float i = 0; i < 256; i += 256 / 42) {
if (index == translatedHue)
return Color.rgb(255, 0, (int) i);
index++;
}
for (float i = 0; i < 256; i += 256 / 42) {
if (index == translatedHue)
return Color.rgb(255 - (int) i, 0, 255);
index++;
}
for (float i = 0; i < 256; i += 256 / 42) {
if (index == translatedHue)
return Color.rgb(0, (int) i, 255);
index++;
}
for (float i = 0; i < 256; i += 256 / 42) {
if (index == translatedHue)
return Color.rgb(0, 255, 255 - (int) i);
index++;
}
for (float i = 0; i < 256; i += 256 / 42) {
if (index == translatedHue)
return Color.rgb((int) i, 255, 0);
index++;
}
for (float i = 0; i < 256; i += 256 / 42) {
if (index == translatedHue)
return Color.rgb(255, 255 - (int) i, 0);
index++;
}
return Color.RED;
}
// Update the main field colors depending on the current selected hue
private void updateMainColors() {
int mainColor = getCurrentMainColor();
int index = 0;
int[] topColors = new int[256];
for (int y = 0; y < 256; y++) {
for (int x = 0; x < 256; x++) {
if (y == 0) {
mMainColors[index] = Color.rgb(
255 - (255 - Color.red(mainColor)) * x / 255,
255 - (255 - Color.green(mainColor)) * x / 255,
255 - (255 - Color.blue(mainColor)) * x / 255);
topColors[x] = mMainColors[index];
} else
mMainColors[index] = Color.rgb(
(255 - y) * Color.red(topColors[x]) / 255,
(255 - y) * Color.green(topColors[x]) / 255,
(255 - y) * Color.blue(topColors[x]) / 255);
index++;
}
}
}
#Override
protected void onDraw(Canvas canvas) {
int translatedHue = 255 - (int) (mCurrentHue * 255 / 360);
// Display all the colors of the hue bar with lines
for (int x = 0; x < 256; x++) {
// If this is not the current selected hue, display the actual
// color
if (translatedHue != x) {
mPaint.setColor(mHueBarColors[x]);
mPaint.setStrokeWidth(1);
} else // else display a slightly larger black line
{
mPaint.setColor(Color.BLACK);
mPaint.setStrokeWidth(3);
}
canvas.drawLine(x + 10, 0, x + 10, 40, mPaint);
// canvas.drawLine(0, x+10, 40, x+10, mPaint);
//canvas.drawLine(x + width/27, 0, x + width/27,height/8 , mPaint);
}
// Display the main field colors using LinearGradient
for (int x = 0; x < 256; x++) {
int[] colors = new int[2];
colors[0] = mMainColors[x];
colors[1] = Color.BLACK;
Shader shader = new LinearGradient(0, 50, 0, 306, colors, null,
Shader.TileMode.REPEAT);//0,50,0,306
mPaint.setShader(shader);
canvas.drawLine(x + 10, 50, x + 10, 306, mPaint);
//canvas.drawLine(x + width/27, height/8 + 10, x + width/27, height*(5/6), mPaint);
}
mPaint.setShader(null);
// Display the circle around the currently selected color in the
// main field
if (mCurrentX != 0 && mCurrentY != 0) {
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setColor(Color.BLACK);
canvas.drawCircle(mCurrentX, mCurrentY, 10, mPaint);
}
// Draw a 'button' with the currently selected color
mPaint.setStyle(Paint.Style.FILL);
mPaint.setColor(mCurrentColor);
//canvas.drawRect(10, 316, 138, 356, mPaint);
//canvas.drawRect(width/27, height*(5/6), width/2, height, mPaint);
// Set the text color according to the brightness of the color
if (Color.red(mCurrentColor) + Color.green(mCurrentColor)
+ Color.blue(mCurrentColor) < 384)
mPaint.setColor(Color.WHITE);
else
mPaint.setColor(Color.BLACK);
// canvas.drawText(
// "New Color", 74,
//340, mPaint);
// Draw a 'button' with the default color
mPaint.setStyle(Paint.Style.FILL);
mPaint.setColor(mDefaultColor);
//canvas.drawRect(138, 316, 266, 356, mPaint);
//canvas.drawRect(width/2, height*(5/6), width, height, mPaint);
// Set the text color according to the brightness of the color
if (Color.red(mDefaultColor) + Color.green(mDefaultColor)
+ Color.blue(mDefaultColor) < 384)
mPaint.setColor(Color.WHITE);
else
mPaint.setColor(Color.BLACK);
//canvas.drawText(
// "Default Color", 202, 340,
//mPaint);
}
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
setMeasuredDimension(276,366 );//276,366
width = widthMeasureSpec;
height = heightMeasureSpec;
}
#Override
public boolean onTouchEvent(MotionEvent event) {
if (event.getAction() != MotionEvent.ACTION_DOWN)
return true;
float x = event.getX();
float y = event.getY();
// If the touch event is located in the hue bar
if (x > 10 && x < 266 && y > 0 && y < 40) {
// Update the main field colors
mCurrentHue = (255 - x) * 360 / 255;
updateMainColors();
// Update the current selected color
int transX = mCurrentX - 10;
int transY = mCurrentY - 60;
int index = 256 * (transY - 1) + transX;
if (index > 0 && index < mMainColors.length)
mCurrentColor = mMainColors[256 * (transY - 1) + transX];
// Force the redraw of the dialog
invalidate();
}
// If the touch event is located in the main field
if (x > 10 && x < 266 && y > 50 && y < 306) {
mCurrentX = (int) x;
mCurrentY = (int) y;
int transX = mCurrentX - 10;
int transY = mCurrentY - 60;
int index = 256 * (transY - 1) + transX;
if (index > 0 && index < mMainColors.length) {
// Update the current color
mCurrentColor = mMainColors[index];
mListener.colorChanged("", mCurrentColor);
// Force the redraw of the dialog
invalidate();
}
}
// If the touch event is located in the left button, notify the
// listener with the current color
//if (x > 10 && x < 138 && y > 316 && y < 356)
// mListener.colorChanged("", mCurrentColor);
// If the touch event is located in the right button, notify the
// listener with the default color
//if (x > 138 && x < 266 && y > 316 && y < 356)
// mListener.colorChanged("", mDefaultColor);
return true;
}
}
public ColorPickerDialog(Context context, OnColorChangedListener listener,
String key, int initialColor, int defaultColor) {
super(context);
mListener = listener;
mKey = key;
mInitialColor = initialColor;
mDefaultColor = defaultColor;
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
OnColorChangedListener l = new OnColorChangedListener() {
public void colorChanged(String key, int color) {
mListener.colorChanged(mKey, color);
dismiss();
}
};
setContentView(new ColorPickerView(getContext(), l, mInitialColor,
mDefaultColor));
setTitle("Pick Text Color");
}
}
Edit how to use in activity
first make activity
implement OnColorChangedListener
then you get the callback function
#Override
public void colorChanged(String key, int color) {
// TODO Auto-generated method stub
paint.setColor(color);
}
and in your code you can make the dialog with the listener like this
ColorPickerDialog color = new ColorPickerDialog(this,this, "picker",Color.BLACK,Color.WHITE);
color.show();
Hi I am creating an app for android and I encountered a problem with how to color bitmaps
I am using the following simple code
for(int i=0;i<pixels.length;i++){
if(pixels[i] == COLOR.WHITE){
pixels[i]=Color.RED;
}
}
Where pixels is the array of pixels of the bitmap
However the problem is that I'm getting in the edges of the colored area a thin layer of pixels that weren't colored I understand this stems from that this layer of white is somewhat shadowy(not entirely white partially black) how do I get over this?
Hope I made my question clear enough
Right now you are matching and replacing one specific integer value for white. However, in your original bitmap that white color bleeds into other colors and therefore you have white color values around the edges of these white patches that are slightly different.
You need to change your algorithm to take a color matching tolerance into account. For that you'll have to split up your pixel and your key color into their three color channels and check them individually if the differences between them are within a certain tolerance value.
That way you can match these whitish colored pixels around the edges. But even with added tolerance you cannot just replace your matching pixels just with red. You would get aliased hard, red edges and it wouldn't look pretty. I wrote a similar algorithm a while ago and got around that aliasing issue by doing some color blending in HSV color space:
public Bitmap changeColor(Bitmap src, int keyColor,
int replColor, int tolerance) {
Bitmap copy = src.copy(Bitmap.Config.ARGB_8888, true);
int width = copy.getWidth();
int height = copy.getHeight();
int[] pixels = new int[width * height];
src.getPixels(pixels, 0, width, 0, 0, width, height);
int sR = Color.red(keyColor);
int sG = Color.green(keyColor);
int sB = Color.blue(keyColor);
int tR = Color.red(replColor);
int tG = Color.green(replColor);
int tB = Color.blue(replColor);
float[] hsv = new float[3];
Color.RGBToHSV(tR, tG, tB, hsv);
float targetHue = hsv[0];
float targetSat = hsv[1];
float targetVal = hsv[2];
for(int i = 0; i < pixels.length; ++i) {
int pixel = pixels[i];
if(pixel == keyColor) {
pixels[i] = replColor;
} else {
int pR = Color.red(pixel);
int pG = Color.green(pixel);
int pB = Color.blue(pixel);
int deltaR = Math.abs(pR - sR);
int deltaG = Math.abs(pG - sG);
int deltaB = Math.abs(pB - sB);
if(deltaR <= tolerance && deltaG <= tolerance
&& deltaB <= tolerance) {
Color.RGBToHSV(pR, pG, pB, hsv);
hsv[0] = targetHue;
hsv[1] = targetSat;
hsv[2] *= targetVal;
int mixTrgColor = Color.HSVToColor(Color.alpha(pixel),
hsv);
pixels[i] = mixTrgColor;
}
}
}
copy.setPixels(pixels, 0, width, 0, 0, width, height);
return copy;
}
keyColor and replColor are ARGB encoded integer values such as Color.WHITE and Color.RED. tolerance is a value from 0 to 255 that specifies the key color matching tolerance per color channel. I had to rewrite that snippet a bit to remove framework specifics. I hope I didn't make any mistakes.
As a word of warning: Java (on Android) is pretty slow with image processing. If it's not fast enough for you, you should rewrite the algorithm in C for example and use the NDK.
UPDATE: Color replace algorithm in C
Here is the implementation of the same algorithm written in C. The last function is the actual algorithm which takes the bitmap's pixel array as argument. You need to create a header file with that function declaration and set up some NDK compilation boilerplate and create an additional Java class with the following method declaration:
native static void changeColor(int[] pixels, int width, int height, int keyColor, int replColor, int tolerance);
C implementation:
#include <math.h>
#define MIN(x,y) ((x < y) ? x : y)
#define MAX(x,y) ((x > y) ? x : y)
int clamp_byte(int val) {
if(val > 255) {
return 255;
} else if(val < 0) {
return 0;
} else {
return val;
}
}
int encode_argb(uint8_t r, uint8_t g, uint8_t b, uint8_t a) {
return ((a & 0xFF) << 24) | ((r & 0xFF) << 16) | ((g & 0xFF) << 8) | (b & 0xFF);
}
int alpha(int c) {
return (c >> 24) & 0xFF;
}
int red(int c) {
return (c >> 16) & 0xFF;
}
int green(int c) {
return (c >> 8) & 0xFF;
}
int blue(int c) {
return c & 0xFF;
}
typedef struct struct_hsv {
uint16_t h;
uint8_t s;
uint8_t v;
} hsv;
// http://www.ruinelli.ch/rgb-to-hsv
hsv rgb255_to_hsv(uint8_t r, uint8_t g, uint8_t b) {
uint8_t min, max, delta;
hsv result;
int h;
min = MIN(r, MIN(g, b));
max = MAX(r, MAX(g, b));
result.v = max; // v, 0..255
delta = max - min; // 0..255, < v
if(delta != 0 && max != 0) {
result.s = ((int) delta) * 255 / max; // s, 0..255
if(r == max) {
h = (g - b) * 60 / delta; // between yellow & magenta
} else if(g == max) {
h = 120 + (b - r) * 60 / delta; // between cyan & yellow
} else {
h = 240 + (r - g) * 60 / delta; // between magenta & cyan
}
if(h < 0) h += 360;
result.h = h;
} else {
// r = g = b = 0
result.h = 0;
result.s = 0;
}
return result;
}
int hsv_to_argb(hsv color, uint8_t alpha) {
int i;
uint8_t r,g,b;
float f, p, q, t, h, s, v;
h = (float) color.h;
s = (float) color.s;
v = (float) color.v;
s /= 255;
if(s == 0) {
// achromatic (grey)
return encode_argb(color.v, color.v, color.v, alpha);
}
h /= 60; // sector 0 to 5
i = floor(h);
f = h - i; // factorial part of h
p = (unsigned char) (v * (1 - s));
q = (unsigned char) (v * (1 - s * f));
t = (unsigned char) (v * (1 - s * (1 - f)));
switch(i) {
case 0:
r = v;
g = t;
b = p;
break;
case 1:
r = q;
g = v;
b = p;
break;
case 2:
r = p;
g = v;
b = t;
break;
case 3:
r = p;
g = q;
b = v;
break;
case 4:
r = t;
g = p;
b = v;
break;
default: // case 5:
r = v;
g = p;
b = q;
break;
}
return encode_argb(r, g, b, alpha);
}
JNIEXPORT void JNICALL Java_my_package_name_ClassName_changeColor(
JNIEnv* env, jclass clazz, jintArray bitmapArray, jint width, jint height,
jint keyColor, jint replColor, jint tolerance) {
jint* pixels = (*env)->GetPrimitiveArrayCritical(env, bitmapArray, 0);
int sR = red(keyColor);
int sG = green(keyColor);
int sB = blue(keyColor);
int tR = red(replColor);
int tG = green(replColor);
int tB = blue(replColor);
hsv cHsv = rgb255_to_hsv(tR, tG, tB);
int targetHue = cHsv.h;
int targetSat = cHsv.s;
int targetVal = cHsv.v;
int i;
int max = width * height;
for(i = 0; i < max; ++i) {
int pixel = pixels[i];
if(pixel == keyColor) {
pixels[i] = replColor;
} else {
int pR = red(pixel);
int pG = green(pixel);
int pB = blue(pixel);
int deltaR = abs(pR - sR);
int deltaG = abs(pG - sG);
int deltaB = abs(pB - sB);
if(deltaR <= tolerance && deltaG <= tolerance
&& deltaB <= tolerance) {
cHsv = rgb255_to_hsv(pR, pG, pB);
cHsv.h = targetHue;
cHsv.s = targetSat;
int newValue = ((int) cHsv.v * targetVal) / 255;
cHsv.v = newValue;
int mixTrgColor = hsv_to_argb(cHsv, alpha(pixel));
pixels[i] = mixTrgColor;
}
}
}
(*env)->ReleasePrimitiveArrayCritical(env, bitmapArray, pixels, 0);
}
I am working in an android application to draw a circle and divide them equally and bind text inside the divided portion in the circle(like pichart). I have drawn a circle and divided them equally, but I want to bind text inside the divided portion. Please look into my code and give a solution. Thanks in advance.
public class MainActivity extends Activity {
/** Called when the activity is first created. */
float values[] = { 130, 130, 130, 130, 130 };
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
LinearLayout linear = (LinearLayout) findViewById(R.id.linearlay);
values = calculateData(values);
linear.addView(new MyGraphview(this, values));
}
private float[] calculateData(float[] data) {
float total = 0;
for (int i = 0; i < data.length; i++) {
total += data[i];
}
for (int i = 0; i < data.length; i++) {
data[i] = 360 * (data[i] / total);
}
return data;
}
public class MyGraphview extends View {
private Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
private float[] value_degree;
private int[] COLORS = { Color.YELLOW, Color.GREEN, Color.WHITE,
Color.CYAN, Color.RED };
RectF rectf = new RectF(10, 10, 300, 300);
Rect rect = new Rect(10, 10, 300, 300);
int temp = 0;
String rotatedtext;
Path path;
public MyGraphview(Context context, float[] values) {
super(context);
path = new Path();
value_degree = new float[values.length];
for (int i = 0; i < values.length; i++) {
value_degree[i] = values[i];
}
paint.setTextSize(16);
rotatedtext = "Rotated :)";
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
for (int i = 0; i < value_degree.length; i++) {
if (i == 0) {
paint.setColor(COLORS[i]);
canvas.drawArc(rectf, 0, value_degree[i], true, paint);
} else {
temp += (int) value_degree[i - 1];
paint.setColor(COLORS[i]);
canvas.drawArc(rectf, temp, value_degree[i], true, paint); //
}
}
}
}
}
Try this:
private String[] STRINGS = { "Yellow", "GREEN", "WHITE", "CYAN", "RED" }; // Array of strings, just for the sample
#Override
protected void onDraw(Canvas canvas)
{
super.onDraw(canvas);
temp = 0;
int centerX = (rect.left + rect.right) / 2;
int centerY = (rect.top + rect.bottom) / 2;
int radius = (rect.right - rect.left) / 2;
radius *= 0.5; // 1 will put the text in the border, 0 will put the text in the center. Play with this to set the distance of your text.
for (int i = 0; i < data.length; i++)
{
if (i > 0)
temp += (int) data[i - 1]; // rewrote your code here a bit, to avoid duplicate code.
paint.setColor(COLORS[i]);
canvas.drawArc(rectf, temp, data[i], true, paint);
paint.setColor(Color.BLACK); // set this to the text color.
float medianAngle = (temp + (data[i] / 2f)) * (float)Math.PI / 180f; // this angle will place the text in the center of the arc.
canvas.drawText(STRINGS[i], (float)(centerX + (radius * Math.cos(medianAngle))), (float)(centerY + (radius * Math.sin(medianAngle))), paint);
}
}
Also, for nicer results, make sure to set the Align.CENTER property in the paint before drawing any text:
paint.setTextSize(16);
paint.setTextAlign(Align.CENTER);
Hope this helps :)