Decrease the size of the radio button icon - android

i am progrmatically creating radio button, and it works fine,
RadioImageButton RadioImageButton = new RadioImageButton(this);
RadioImageButton.setGravity(Gravity.CENTER);
RadioImageButton.setId(buttonId);
RadioImageButton.setTextColor(Color.BLACK);
RadioImageButton.setCompoundDrawablesWithIntrinsicBounds(icon, null,null, null)// use this to set the icon
RadioImageButton.setBackgroundDrawable(drawable);
RadioGroup.LayoutParams radioImageButtonParams = new RadioGroup.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,
LinearLayout.LayoutParams.MATCH_PARENT, 1f);
radioImageButtonParams.setMargins(0, 0, 1, 0);
RadioGroup.addView(RadioImageButton, radioImageButtonParams);
In RadioImageButton class
Drawable image;
public RadioImageButton(Context context) {
super(context);
setButtonDrawable(android.R.color.transparent);
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (image != null) {
image.setState(getDrawableState());
final int verticalGravity = getGravity() & Gravity.VERTICAL_GRAVITY_MASK;
final int height = image.getIntrinsicHeight();
int y = 0;
switch (verticalGravity) {
case Gravity.BOTTOM:
y = getHeight() - height;
break;
case Gravity.CENTER_VERTICAL:
y = (getHeight() - height) / 2;
break;
}
int buttonWidth = image.getIntrinsicWidth();
int buttonLeft = (getWidth() - buttonWidth) / 3;
image.setBounds(buttonLeft, y, buttonLeft + buttonWidth, y + height);
image.draw(canvas);
}
}
But the icon which is being displayed is big , i need to decrease the size of that icon.
I have tried with setHeight but its not working.
RadioImageButton.setCompoundDrawablesWithIntrinsicBounds(icon, null,null, null)
this is used to set the icon

ok i fixed it by myself , here is the answer
private Drawable resize(Drawable image) {
Bitmap b = ((BitmapDrawable)image).getBitmap();
Bitmap bitmapResized = Bitmap.createScaledBitmap(b, 50, 50, true);// filter attribute set to true
return new BitmapDrawable(bitmapResized);
}
The code above is to modify the size of drawable, and make sure the filter attribute is set to true so that the icons does not look blur.
Hope it helps some one in future. Happy Coding :)

Related

Increasing and decreasing the height of an Image Entity by clicking buttons or seekbar

I made this project from this open source https://github.com/uptechteam/MotionViews-Android
I'm actually creating a Memegenerator app,
The problem is when I resize the height/width of one of the bitmap inside canvas
The bitmap also moving aside, But it actually should not move from x y axis while I scroll the seekbar, Thats the problem.
This is the ImageEntity class
public ImageEntity(#NonNull Layer layer,
#NonNull Bitmap bitmap,
#IntRange(from = 1) int canvasWidth,
#IntRange(from = 1) int canvasHeight) {
super(layer, canvasWidth, canvasHeight);
this.bitmap = bitmap;
layer.widthSize(bitmap.getWidth());
layer.heightSize(bitmap.getHeight());
updateIMGEntity(false);
}
public void updateIMGEntity() {
updateIMGEntity(true);
}
private void updateIMGEntity(boolean moveToPreviousCenter) {
// save previous center
PointF oldCenter = absoluteCenter();
Bitmap newBitmap = Bitmap.createScaledBitmap(bitmap, layer.getWidth(),
layer.getHeight(), false);
// recycle previous bitmap (if not reused) as soon as possible
if (bitmap != null && bitmap != newBitmap && !bitmap.isRecycled()) {
bitmap.recycle();
}
this.bitmap = newBitmap;
float width = bitmap.getWidth();
float height = bitmap.getHeight();
#SuppressWarnings("UnnecessaryLocalVariable")
float widthAspect = 1.0F * canvasWidth / height;
// for text we always match text width with parent width
this.holyScale = widthAspect;
// initial position of the entity
srcPoints[0] = 0; srcPoints[1] = 0;
srcPoints[2] = width; srcPoints[3] = 0;
srcPoints[4] = width; srcPoints[5] = height;
srcPoints[6] = 0; srcPoints[7] = height;
srcPoints[8] = 0; srcPoints[8] = 0;
if (moveToPreviousCenter) {
// move to previous center
moveCenterTo(oldCenter);
}
}
#Override
public void drawContent(#NonNull Canvas canvas, #Nullable Paint drawingPaint) {
//updateMatrix();
canvas.drawBitmap(bitmap, matrix, drawingPaint);
//release();
}
Please someone help me.

Nine-patch content area not working

I'm trying to make a frame for TextView as a cloud. But the content area does not behave as expected. What am i doing wrong?
I have a suggestion that is not working properly because the content area less scale area. So sad. I remade it to handle 9-patch manually. Save pictures without .9.png. Get Bitmap. There are 9-line present. With getPixels calculated padding and set it on the TextView. After that calculating and set LayoutParams.width and LayoutParams.height. Looks a bit ugly, but it works quite quickly, and most importantly correctly.
private int startX=-1;
private int endX=-1;
private int contentW=-1;
private int contentH=-1;
Bitmap bmp=BitmapFactory.decodeResource(getResources(), mIconResId);
int[] pixels=new int[bmp.getWidth()*bmp.getHeight()];
bmp.getPixels(pixels, 0, bmp.getWidth(), 0, 0, bmp.getWidth(),bmp.getHeight());
for(int i=0;i<bmp.getWidth();i++){
if(startX==-1 && pixels[bmp.getWidth()*(bmp.getHeight()-1)+i]==Color.BLACK){
startX=i;
}
if(startX!=-1 && pixels[bmp.getWidth()*(bmp.getHeight()-1)+i]!=Color.BLACK){
endX=i;
break;
}
}
int startY=-1;
int endY=-1;
for(int i=0;i<bmp.getHeight();i++){
if(startY==-1 && pixels[bmp.getWidth()*(i+1)-1]==Color.BLACK){
startY=i;
}
if(startY!=-1 && pixels[bmp.getWidth()*(i+1)-1]!=Color.BLACK){
endY=i;
break;
}
}
setBackground(new BitmapDrawable(getResources(),Bitmap.createBitmap(bmp, 1, 1, bmp.getWidth()-2, bmp.getHeight()-2)));
contentW=endX-startX;
endX=bmp.getWidth()-endX;
contentH=endY-startY;
endY=bmp.getHeight()-endY;
new Handler().post(new Rannable(){
#Override
public void run() {
int w=textview.getWidth();
int h=textview.getHeight();
if(w>endX-startX){
float k=((float)w)/contentW;
startX=(int) (startX*k);
endX=(int) (endX*k);
}
if(h>endY-startY){
float k=((float)h)/contentH;
startY=(int) (startY*k);
endY=(int) (endY*k);
}
w+=startX+startX;
h+=startY+endY;
textview.setPadding(startX, startY, endX, endY);
LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(w,h);
textview.setLayoutParams(lp);
}
});
You set good values for right and bottom borders. You just have to set same values for left and top borders, left border = right border and top border = bottom border.
The result in draw9patch:
And here the 9-patch file:
For your information, your image is not really suitable for using with 9-patch format.
I extended/adapted #ahtartam code. I am not sure if it is the cleanest way but it works for me. If someone needs help, just contact me or ask in comments!
public void setTextLayout(int orgW, int orgH,int actW,int actH,int top,int left) {
int startX = -1;
int endX = -1;
int startY = -1;
int endY = -1;
int contentW;
int contentH;
Bitmap bmp = BitmapFactory.decodeResource(getResources(), R.drawable.image);
int[] pixels = new int[orgW * orgH];
bmp.getPixels(pixels, 0, orgW, 0, 0, orgW, orgH);
for (int i = 0; i < orgW; i++) {
if (startX == -1 && pixels[orgW * (orgH - 1) + i] == Color.BLACK) {
startX = i;
}
if (startX != -1 && pixels[orgW * (orgH - 1) + i] != Color.BLACK) {
endX = i;
break;
}
}
for (int i = 0; i < orgH; i++) {
if (startY == -1 && pixels[orgW * (i + 1) - 1] == Color.BLACK) {
startY = i;
}
if (startY != -1 && pixels[orgW * (i + 1) - 1] != Color.BLACK) {
endY = i;
break;
}
}
m_marvin.setImageDrawable(new BitmapDrawable(getResources(), Bitmap.createBitmap(bmp, 1, 1, orgW - 2, orgH - 2)));
RelativeLayout.LayoutParams rp = (RelativeLayout.LayoutParams) m_marvin.getLayoutParams();
contentW=endX- startX;
contentH=endY-startY;
endX=orgW-endX;
endY=orgH-endY;
double scaleX = ((double)actW) / bmp.getWidth();
double scaleY = ((double)actH) / bmp.getHeight();
startX = (int) (startX * scaleX);
endX = (int) (endX * scaleX);
startY = (int) (startY * scaleY);
endY = (int) (endY * scaleY) ;
RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams((int)(contentW*scaleX),(int)(contentH*scaleY));
layoutParams.setMargins(startX+rp.leftMargin+left, startY+rp.topMargin+top, endX+rp.rightMargin, endY+rp.bottomMargin);
layoutParams.addRule(RelativeLayout.CENTER_HORIZONTAL,RelativeLayout.TRUE);
m_text.setLayoutParams(layoutParams);
m_text.bringToFront();
}
Instead TextView I use SizeAwareImageView from -> https://stackoverflow.com/a/15538856/1438596
In my case it looks like this->
public class SizeAwareImageView extends ImageView {
MainActivity m_mainActivity;
public SizeAwareImageView(Context context,AttributeSet attrss){
super(context,attrss);
m_mainActivity = (MainActivity)context;
}
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
if(m_mainActivity.getTextMeasured())return;
// Get image matrix values and place them in an array
float[] f = new float[9];
getImageMatrix().getValues(f);
// Extract the scale values using the constants (if aspect ratio maintained, scaleX == scaleY)
final float scaleX = f[Matrix.MSCALE_X];
final float scaleY = f[Matrix.MSCALE_Y];
// Get the drawable (could also get the bitmap behind the drawable and getWidth/getHeight)
final Drawable d = getDrawable();
final int origW = d.getIntrinsicWidth();
final int origH = d.getIntrinsicHeight();
// Calculate the actual dimensions
final int actW = Math.round(origW * scaleX);
final int actH = Math.round(origH * scaleY);
int top = (int) (imgViewH - actH)/2;
int left = (int) (imgViewW - actW)/2;
if(origW!=actW){
m_mainActivity.setTextMeasured(true);
m_mainActivity.setTextLayout(origW, origH, actW, actH,top,left);
}
}
}
You could use this tool for creating your nine-patch images.

getPixels and setPixels on canvas drawn objects

I have created a diagonal white line on a custom view from one corner of screen to another corner using this-
canvas.drawLine(0, 0, MainActivity.width+10, MainActivity.height, paint);
I know how to getPixels and setPixels on a Bitmap, like this-
public Bitmap generateAlphaMask(Bitmap bmpTop,Bitmap bmpBottom) {
int width = bmpTop.getWidth();
int height = bmpTop.getHeight();
boolean[][] res = new boolean[width][height];
int[] colors = new int[width * height];
bmpTop.getPixels(colors, 0, width, 0, 0, width, height);
for (int x = 0; x < width; ++x) {
for (int y = 0; y < height; ++y) {
int cell = y * width + x;
int redVal = Color.red(colors[cell]);
int greenVal = Color.green(colors[cell]);
int blueVal = Color.blue(colors[cell]);
int alpha = Color.alpha(colors[cell]);
res[x][y] = alpha == ALPHA_THRESHOLD;
if (res[x][y]) {
bmpBottom.setPixel(x, y, Color.TRANSPARENT);
}
}
}
return bmpBottom;
}
But I want to store Pixel Positions from canvas where the pixel is "not white".
Help me regarding this.

Making custom view bigger in the y

I have a custom view and I'm trying to dynamically make it bigger in the Y direction. That is the only direction that doesn't work. If I adjust any of the other variables in my custom view the rectangle gets affected in the appropriate ways. If I try adding to bottomY then the bottom border disappears and nothing draws below that. Here is the code for the view:
private class RectView extends View{
float leftX, rightX, topY, bottomY;
boolean isAppt;
boolean isBeforeTime;
boolean isSelected;
public Paint rectPaint;
private RectF rectangle;
String time;
public RectView(Context context, float _leftX, float _rightX, float _topY, float _bottomY,
boolean _isAppt, boolean _isBeforeTime, String _time){
super(context);
leftX = _leftX;
rightX = _rightX;
topY = _topY;
bottomY = _bottomY;
isAppt = _isAppt;
isBeforeTime = _isBeforeTime;
time = _time;
init();
}
private void init(){
rectPaint = new Paint();
if(leftX > rightX || topY > bottomY)
Toast.makeText(context, "Incorrect", Toast.LENGTH_SHORT).show();
MyUtility.LogD_Common("Left = " + leftX + ", Top = " + topY + ", Right = " + rightX +
", Bottom = " + bottomY);
rectangle = new RectF(leftX, topY, rightX, bottomY);
float height = bottomY;
float width = rightX - leftX;
MyUtility.LogD_Common("Height = " + height + ", Width = " + width);
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.FILL_PARENT, (int) height);
//params.leftMargin = (int) leftX;
params.bottomMargin = 10;
//params.rightMargin = 10;
setLayoutParams(params);
}
protected void onDraw(Canvas canvas){
MyUtility.LogD_Common("Right = " + rightX);
rectangle.left = leftX;
rectangle.right = rightX;
rectangle.top = topY;
rectangle.bottom = bottomY;
if(!isSelected){
if(isAppt){
if(isBeforeTime)
rectPaint.setARGB(144, 119, 98, 95);
else
rectPaint.setARGB(144, 217, 131, 121);
//119,98,95
rectPaint.setStyle(Style.FILL);
}
else{
rectPaint.setARGB(0, 0, 0, 0);
rectPaint.setStyle(Style.FILL);
}
canvas.drawRect(rectangle, rectPaint);
if(isAppt){
rectPaint.setColor(Color.RED);
rectPaint.setStrokeWidth(2);
rectPaint.setStyle(Style.STROKE);
canvas.drawRect(rectangle, rectPaint);
}
}
else{
rectPaint.setARGB(144, 197, 227, 191);
rectPaint.setStyle(Style.FILL);
canvas.drawRect(rectangle, rectPaint);
rectPaint.setColor(Color.GREEN);
rectPaint.setStrokeWidth(2);
rectPaint.setStyle(Style.STROKE);
canvas.drawRect(rectangle, rectPaint);
}
}
}
Why is this happening and why only in the positive Y direction?
When you create this object you call init(), where you set the height spec for your RelativeLayout params to the local variable height, which you define with:
float height = bottomY;
By doing this, you are telling the parent RelativeLayout that this view want's to be exactly that height that bottomY was when you created the object.
If you then increase the value of bottomY for your already created object, it can no longer fit inside the height you defined in your RelativeLayout params when the object was first created.
Firstly, Changing the LayoutParams from inside the class in this way is not recommended. This makes your custom View inflexible. If you set a bunch of RelativeLayout.LayoutParams inside the class, then your custom View can only ever be used in a RelativeLayout.
You should instead set the LayoutParams in your code before you add the view. For example:
RectView rectView = new RectView(...);
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
addView(rectView, params);
Secondly, when the system draws the layout that your custom view has been added to, it goes through a series of steps. In the layout process it will call getMeasuredWidth() and getMeasuredHeight() on all it's child views (including your custom view). You should override your custom views onMeasure() method and get it to report the correct size of your view. Have a look at onMeasure() in the example in the reference documentation for ViewGroup. It's a more complex onMeasure() than you need for your case, but it gives you the basic idea.
In your particular case something like the following should do the trick:
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int width = measureWidth(widthMeasureSpec);
int height = measureHeight(heightMeasureSpec);
setMeasuredDimension(width, height);
}
// This method calculates the Width of your view based on the dimensions of
// your rectangle and the current widthMeasureSpec.
private int measureWidth(int widthMeasureSpec) {
int result = 0;
int specMode = MeasureSpec.getMode(widthMeasureSpec);
int specSize = MeasureSpec.getSize(widthMeasureSpec);
if (specMode == MeasureSpec.EXACTLY) {
// We were told how big to be
result = specSize;
} else {
// Return the width of the rectangle
result = rightX - leftX;
}
return result;
}
// This method calculates the Height of your view based on the dimensions of
// your rectangle and the current widthMeasureSpec.
private int measureHeight(int heightMeasureSpec) {
int result = 0;
int specMode = MeasureSpec.getMode(heightMeasureSpec);
int specSize = MeasureSpec.getSize(heightMeasureSpec);
if (specMode == MeasureSpec.EXACTLY) {
// We were told how big to be
result = specSize;
} else {
// Return the height of the rectangle
result = bottomY - topY;
}
return result;
}

Android: Convert Grayscale to Binary Image

i hava done with get grayscale value, but i don't know how to use function to convert the grayscale to be binary image. Please help me, here my function code:
public Bitmap toBinary(Bitmap bmpOriginal) {
int width, height, threshold;
height = bmpOriginal.getHeight();
width = bmpOriginal.getWidth();
threshold = 127;
final Bitmap bmpBinary = null;
for(int x = 0; x < width; ++x) {
for(int y = 0; y < height; ++y) {
// get one pixel color
int pixel = bmpOriginal.getPixel(x, y);
//get grayscale value
int gray = (int)(pixel & 0xFF);
//get binary value
if(gray < threshold){
bmpBinary.setPixel(x, y, 0);
} else{
bmpBinary.setPixel(x, y, 255);
}
}
}
return bmpBinary;
}
here my full code:
public class MainActivity extends Activity {
ImageView img;
Button btn;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//convert imageview to bitmap
img =(ImageView) findViewById(R.id.imageView1);
BitmapDrawable drawable = (BitmapDrawable) img.getDrawable();
final Bitmap imgbitmap = drawable.getBitmap();
btn.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
//convert bitmap to grayscale
Bitmap imgnew;
imgnew = toGrayscale(imgbitmap);
//convert to binary
imgnew = toBinary(imgnew);
//convert bitmap to imageview
ImageView imgbit;
imgbit = (ImageView) findViewById(R.id.imageView2);
imgbit.setImageBitmap(imgnew);
}
});
}
public Bitmap toGrayscale(Bitmap bmpOriginal){
int width, height;
height = bmpOriginal.getHeight();
width = bmpOriginal.getWidth();
Bitmap bmpGrayscale = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565);
Canvas c = new Canvas(bmpGrayscale);
Paint paint = new Paint();
ColorMatrix cm = new ColorMatrix();
cm.setSaturation(0);
ColorMatrixColorFilter f = new ColorMatrixColorFilter(cm);
paint.setColorFilter(f);
c.drawBitmap(bmpOriginal, 0, 0, paint);
return bmpGrayscale;
}
public Bitmap toBinary(Bitmap bmpOriginal) {
int width, height, threshold;
height = bmpOriginal.getHeight();
width = bmpOriginal.getWidth();
threshold = 127;
final Bitmap bmpBinary = null;
for(int x = 0; x < width; ++x) {
for(int y = 0; y < height; ++y) {
// get one pixel color
int pixel = bmpOriginal.getPixel(x, y);
//get grayscale value
int gray = (int)(pixel & 0xFF);
//get binary value
if(gray < threshold){
bmpBinary.setPixel(x, y, 0);
} else{
bmpBinary.setPixel(x, y, 255);
}
}
}
return bmpBinary;
}
}
First, you get a NullReferenceException because bmpBinary is NULL.
Second, to get one Color chanel you can use int red = Color.red(pixel);
Third, to set a pixel white use bmpBinary.setPixel(x, y, 0xFFFFFFFF);
I modified your code a bit:
public Bitmap toBinary(Bitmap bmpOriginal) {
int width, height, threshold;
height = bmpOriginal.getHeight();
width = bmpOriginal.getWidth();
threshold = 127;
Bitmap bmpBinary = Bitmap.createBitmap(bmpOriginal);
for(int x = 0; x < width; ++x) {
for(int y = 0; y < height; ++y) {
// get one pixel color
int pixel = bmpOriginal.getPixel(x, y);
int red = Color.red(pixel);
//get binary value
if(red < threshold){
bmpBinary.setPixel(x, y, 0xFF000000);
} else{
bmpBinary.setPixel(x, y, 0xFFFFFFFF);
}
}
}
return bmpBinary;
}
An even better way is not to use just the value of one color chanel but a weighted average of red green and blue for example:
int gray = (int)(red * 0.3 + green * 0.59 + blue * 0.11);

Categories

Resources