Am creating an app, in which it detects circles/dots (might be irregular) in an image.To detect it I converted the RGB image to Binary. Using threshold values, I got the sample Binary image given below.
In the image, i want to eliminate the two bigger shapes and i want to detect the small dots/circles, without using any libraries like OpenCV4android. Please help me to solve this.
Here is the program to convert the image to binary:
public class MainActivity extends Activity {
ImageView img;
Button btn;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button btn = (Button)findViewById(R.id.button);
//convert imageview to bitmap
img =(ImageView) findViewById(R.id.imageView);
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 = 65;
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,0xFFFFFFFF );
} else{
bmpBinary.setPixel(x, y,0xFF000000 );
}
}
}
return bmpBinary;
}
}
Related
now I am getting only one Text over the image I am using Canvas and Bitmap :
here is my code :
public Bitmap drawTextArrayToBitmap(Context mContext, int resourceId,String mText) {
try {
Resources resources = mContext.getResources();
float scale = resources.getDisplayMetrics().density;
Bitmap bitmap = BitmapFactory.decodeResource(resources, resourceId);
android.graphics.Bitmap.Config bitmapConfig = bitmap.getConfig();
if(bitmapConfig == null) {
bitmapConfig = android.graphics.Bitmap.Config.ARGB_8888;
}
bitmap = bitmap.copy(bitmapConfig, true);
Canvas canvas = new Canvas(bitmap);
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
paint.setColor(Color.rgb(110,110, 110));
paint.setTextSize((int) (12 * scale));
paint.setShadowLayer(1f, 0f, 1f, Color.DKGRAY);
Rect bounds = new Rect();
paint.getTextBounds(mText, 0, mText.length(), bounds);
/* int x = (bitmap.getWidth() - bounds.width())/6;
int y = (bitmap.getHeight() + bounds.height())/5;*/
int x = 100, y = 100;
for(int i=0;i<20;i++)
{
canvas.drawText(mText, x * scale, y * scale, paint);
}
return bitmap;
} catch (Exception e) {
// TODO: handle exception
return null;
}
}
inside oncreate ;
ImageView mImageView = (ImageView)findViewById(R.id.imageView1);
// Bitmap bmp =drawTextToBitmap(this,R.drawable.man,"Hello Android");
Bitmap bmp =drawTextArrayToBitmap(this,R.drawable.man,"Smile");
mImageView.setImageBitmap(bmp);
In this above code, I want to add multiple texts on random position over Image and different style I have tried much time I could not get succeed yet. I have tried inside loop also.
Thank you in Advance I would appreciate your effort
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.
I've got two ImageViews within a RelativeLayout. One ImageView is draggable and scalable upon the other ImageView. This all works fine except when I try to export those ImageViews to a bitmap and add it to a canvas.
I can't figure out how to calculate the scale and dragged position of view/bitmap B.
ImageView A functions as a background.
ImageView B is draggable and scalable on top of ImageView A.
Here is a code example
public static Bitmap MergeBitmaps(View v, View ViewA, Bitmap bitmapA, View viewB, Bitmap bitmapB) {
Bitmap b = Bitmap.createBitmap(
bitmapA.getWidth(), bitmapA.getHeight(), Bitmap.Config.ARGB_8888);
Canvas c = new Canvas(b);
float scaleFactor = (float) ViewA.getHeight() / (float) bitmapA.getHeight();
float scaleFactorWidth = (float) ViewA.getWidth() / (float)bitmapA.getWidth();
int test2[] = new int[2];
viewB.getLocationOnScreen(test2);
//Rect rect1 = new Rect();
//selectedImg.getDrawingRect(rect1);
//Rect rect2 = new Rect();
//logo.getDrawingRect(rect2);
//int logoHeight = logo.getHeight();
//int logoWidth = logo.getWidth();
//int logoLeft = logo.getLeft();
//int selectedImgLeft = selectedImg.getLeft();
float scaleFactorMid = (scaleFactor + scaleFactorWidth)/2;
c.drawBitmap(bitmapA, 0, 0, null);
//c.drawBitmap(logoBitmap, test2[0]*scaleFactorWidth, test2[1]*scaleFactor, null);
bitmapB = getResizedBitmap(bitmapB, (int)(bitmapB.getHeight()*scaleFactorMid), (int)(bitmapB.getWidth()*scaleFactorMid));
c.drawBitmap(bitmapB, bitmapA.getWidth()/2, bitmapA.getHeight()/2, null);
//v.layout(0, 0, v.getWidth(), v.getHeight());
//selectedImg.draw(c);
return b;
}
I tried calculating the scale factor by dividing the view's width/height and the Bitmaps width/height.
I tried a lot more as you can see. Can anyone point me in the right direction?
For your reference below function are helpful,(In this i scaled bitmap statically, you can move the code).
public void mergeTwoBitmap() {
ImageView iv1 = (ImageView) findViewById(R.id.imageView1);
ImageView iv2 = (ImageView) findViewById(R.id.imageView2);
Bitmap bitmap1 = ((BitmapDrawable) iv1.getDrawable()).getBitmap();
Bitmap bitmap2 = ((BitmapDrawable) iv2.getDrawable()).getBitmap();
float img2X = iv2.getX(), img2Y = iv2.getY();
float img2Width = bitmap2.getWidth(), img2Height = bitmap2.getHeight(); // Original Width And Height
bitmap2 = Bitmap.createScaledBitmap(bitmap2, 300, 300, true);
float img2NewX, img2NewY;
img2NewX = img2X + (img2Width - bitmap2.getWidth()) * 0.5f; // here bitmap2.getWidth() after scale bitmap1
img2NewY = img2Y + (img2Height - bitmap2.getHeight()) * 0.5f; // here bitmap2.getHeight() after scale bitmap2
Bitmap b = mergeBitmap(iv1.getWidth(), iv1.getHeight(), bitmap1,
bitmap2, img2NewX, img2NewY);
}
private Bitmap mergeBitmap(float w, float h, Bitmap bmp1, Bitmap bmp2,
float x, float y) {
Bitmap cs = null;
int width = (int) w, height = (int) h;
cs = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
Canvas comboImage = new Canvas(cs);
comboImage.drawBitmap(
Bitmap.createScaledBitmap(bmp1, width, height, true), 0f, 0f,
null);
comboImage.drawBitmap(bmp2, x, y, null);
return cs;
}
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);
How can i to get color/alpha of pixel from Sprite in andengine without creating any additional Bitmap?
I solved this problem by using this function
private void loadObjectsMask()
{
InputStream in = null;
Bitmap maskForObjects=null;
try {
final BitmapFactory.Options decodeOptions = new BitmapFactory.Options();
decodeOptions.inPreferredConfig = Bitmap.Config.ARGB_4444;
in = GameActivity.this.getAssets().open("images/" + BACKGROUND_PATH + getObjectImgFile());
maskForObjects = BitmapFactory.decodeStream(in, null, decodeOptions);
} catch (final IOException e) {
} finally {
StreamUtils.close(in);
}
if (maskForObjects != null)
{
objectsMask=new byte[maskForObjects.getWidth()][maskForObjects.getHeight()];
for(int pw=0;pw<maskForObjects.getWidth();++pw)
{
for(int ph=0;ph<maskForObjects.getHeight();++ph)
{
objectsMask[pw][ph]=(byte)(Color.alpha(maskForObjects.getPixel(pw, ph))==0?0:1);
}
}
maskForObjects.recycle();
System.out.printf("Bitmap size %d %d\n", maskForObjects.getWidth(),maskForObjects.getHeight());
}
else System.out.printf("Bitmap size error\n");
}
have a look this method, this method are used to effect on each pix
public Bitmap invert(Bitmap src) {
// image size
int width = src.getWidth();
int height = src.getHeight();
// create output bitmap
Bitmap bmOut = Bitmap.createBitmap(width, height, src.getConfig());
// color information
int A, R, G, B;
int pixel;
// 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);
// get color on each channel
A = Color.alpha(pixel);
R = Color.red(pixel);
G = Color.green(pixel);
B = Color.blue(pixel);
// set new pixel color to output image
bmOut.setPixel(x, y, Color.argb(A, 255-R, 255-G, 255-B));
}
}
// return final image
return bmOut;
}
To convert Gray Scale
public static 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;
}