I want to create application like this.
Flood fill algorithm
I applied that code and it is working fine with JPG or PNG file.
But I want to use that algorithm with Vector drawable imageview
Vector drawable imageview before flood fill
After flood fill of vector imageview
Expected result should be like this (Flood fill work perfectly when I set JPG or PNG file)
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_flood_fill);
iv_FloodFillActivity_image = findViewById(R.id.iv_FloodFillActivity_image);
iv_FloodFillActivity_image.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
floodColor(event.getX(), event.getY());
}
return true;
}
});
}
private void floodColor(float x, float y) {
final Point p1 = new Point();
p1.x = (int) x;// X and y are co - ordinates when user clicks on the screen
p1.y = (int) y;
Bitmap bitmap = getBitmapFromVectorDrawable(iv_FloodFillActivity_image.getDrawable());
//bitmap = bitmap.copy(Bitmap.Config.ARGB_8888, true);
int pixel = bitmap.getPixel((int) x, (int) y);
int[] sourceColorRGB = new int[]{
Color.red(pixel),
Color.green(pixel),
Color.blue(pixel)
};
final int targetColor = Color.parseColor("#FF2200");
QueueLinearFloodFiller queueLinearFloodFiller = new QueueLinearFloodFiller(bitmap, sourceColor, targetColor);
int toleranceHex = Color.parseColor("#545454");
int[] toleranceRGB = new int[]{
Color.red(toleranceHex),
Color.green(toleranceHex),
Color.blue(toleranceHex)
};
queueLinearFloodFiller.setTolerance(toleranceRGB);
queueLinearFloodFiller.setFillColor(targetColor);
queueLinearFloodFiller.setTargetColor(sourceColorRGB);
queueLinearFloodFiller.floodFill(p1.x, p1.y);
bitmap = queueLinearFloodFiller.getImage();
iv_FloodFillActivity_image.setImageBitmap(bitmap);
}
private Bitmap getBitmapFromVectorDrawable(Drawable drawable) {
try {
Bitmap bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
drawable.draw(canvas);
return bitmap;
} catch (OutOfMemoryError e) {
return null;
}
}
Check Class : QueueLinearFloodFiller
How can I use vector drawable?
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 am just creating an application in which I need to drill into the bitmap, I succeed for that also but bitmap drill is lagging as I touch image view. Any help on this is really appreciated...Thanks..
Here is Main File
public class MainActivity extends Activity{
int x, y;
Bitmap background,foreground;
ImageView iv;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
iv = (ImageView) findViewById(R.id.img);
background = BitmapFactory.decodeResource(getResources(), R.mipmap.mug_shot);
foreground = BitmapFactory.decodeResource(getResources(), R.mipmap.poster);
iv.setImageBitmap(combineTwoBitmaps(background, foreground));
iv.setOnTouchListener(new View.OnTouchListener()
{
#Override
public boolean onTouch(View view, MotionEvent event)
{
int action = event.getAction();
switch (action) {
case MotionEvent.ACTION_MOVE:
x = (int) (event.getRawX()+100);
y = (int) (event.getY()+100);
System.out.println("X : "+ x +" Y : "+ y);
foreground = punchAHoleInABitmap(foreground);
iv.setImageBitmap(combineTwoBitmaps(background,foreground));
System.out.println("Hello this is Test2");
break;
case MotionEvent.ACTION_CANCEL:
break;
default:
break;
}
return true;
}
});
}
private Bitmap punchAHoleInABitmap(Bitmap foreground)
{
System.out.println("Hello this is Tesyt");
Bitmap bitmap = Bitmap.createBitmap(foreground.getWidth(), foreground.getHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
Paint paint = new Paint();
canvas.drawBitmap(foreground, 0, 0, paint);
paint.setAntiAlias(true);
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
float radius = (float)(getScreenSize().x *.35);
float x1 = (float) ((x*.5) + (radius * .5));
float y1 = (float) ((y*.5) + (radius * .5));
System.out.println("X1 : "+ x1 +" Y1 : "+ y1);
canvas.drawCircle(x1, y1, 50, paint);
return bitmap;
}
private Bitmap combineTwoBitmaps(Bitmap background, Bitmap foreground) {
Bitmap combinedBitmap = Bitmap.createBitmap(background.getWidth(), background.getHeight(), background.getConfig());
Canvas canvas = new Canvas(combinedBitmap);
Paint paint = new Paint(Paint.FILTER_BITMAP_FLAG);
canvas.drawBitmap(background, 0, 0, paint);
canvas.drawBitmap(foreground, 0, 0, paint);
return combinedBitmap;
}
private Point getScreenSize() {
WindowManager window = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
Display display = window.getDefaultDisplay();
Point size = new Point();
display.getSize(size);
return size;
}
}
ACTION_MOVE is called many times when users slide the screen. This means you will create quite amount of bitmaps in short time.
With GestureDetector you can detect exact one slide/swipe/fling.
The first bitmap is set to fill the entire canvas. I then add another bitmap that has been created from an imageview using:
tattoo.buildDrawingCache();
Bitmap bit2 = tattoo.getDrawingCache();
I then want to add this bitmap over the other keeping it's same scale, rotation, and translation relative to the other bitmap. My issue is that, while the scale and rotation seem fine, the translation shifts to one side or the other.
public static Bitmap overlay(Bitmap bmp1, Bitmap bmp2) {
Bitmap bmOverlay = Bitmap.createBitmap(bmp1.getWidth(), bmp1.getHeight(), bmp1.getConfig());
Canvas canvas = new Canvas(bmOverlay);
canvas.drawBitmap(bmp1, 0,0 , null);
Matrix matrix = new Matrix();
matrix.setScale(tattoo.getScaleX() / imageView.getScaleX(), tattoo.getScaleY() / imageView.getScaleY());
int[] tattooCoords = getRelativeCoords(tattoo);
int[] imageViewCoords = getRelativeCoords(imageView);
matrix.setTranslate(tattooCoords[0] - imageViewCoords[0], tattooCoords[1] - imageViewCoords[1]);
matrix.postRotate(tattoo.getRotation(), tattoo.getX() + tattoo.getWidth() / 2,
tattoo.getY() + tattoo.getHeight() / 2);
canvas.drawBitmap(bmp2, matrix, null);
bmp1.recycle();
bmp2.recycle();
return bmOverlay;
}
private static int[] getRelativeCoords(View v){
View parent = v.getRootView();
int[] viewLocation = new int[2];
v.getLocationInWindow(viewLocation);
int[] rootLocation = new int[2];
parent.getLocationInWindow(rootLocation);
int relativeLeft = viewLocation[0] - rootLocation[0];
int relativeTop = viewLocation[1] - rootLocation[1];
return new int[]{relativeLeft, relativeTop};
}
public static Bitmap combineBitmap(Bitmap background, Bitmap foreground) {
Bitmap result;
try {
if (background == null) {
return null;
}
int bgWidth = background.getWidth();
int bgHeight = background.getHeight();
int fgWidth = foreground.getWidth();
int fgHeight = foreground.getHeight();
result = Bitmap.createBitmap(bgWidth, bgHeight, Config.ARGB_8888);
Canvas cv = new Canvas(result);
cv.drawBitmap(background, 0, 0, null);
cv.drawBitmap(foreground, (bgWidth - fgWidth) / 2, (bgHeight - fgHeight) / 2, null);
cv.save(Canvas.ALL_SAVE_FLAG);
cv.restore();
return result;
} catch (Exception e) {
return null;
}
}
Check whether both Images have equal images have same height and width, then check for every pixel is equal.
boolean imagesEqualCheck(Image img1, Image img2)
{
if (img1.getHeight() != img2.getHeight()) return false;
if (img1.getWidth() != img2.getWidth()) return false;
for (int y = 0; y < img1.getHeight(); ++y)
for (int x = 0; x < img1.getWidth(); ++x)
if (img1.getPixel(x, y) != img2.getPixel(x, y)) return false;
return true;
}
I want to get the co-ordinates of the ImageView, Irrespective of device size.
Is there any possible way !!
I have tried to create specific size for the ImageView,Even specific size for the Parent View also ,but its not working.
I have tried the following possible ways.
int[] posXY = new int[2];
imageview.getLocationOnScreen(posXY);
int MoveX = posXY[0];
int MoveY = posXY[1];
I have tried with Matrix too ,But not working.
Matrix m = imageview.getImageMatrix();
Tried the below code, but it is also not working.!!
I need to get the same {x,y} Co-ordinates for all devices for the same point (Location).
final float[] getPointerCoords(ImageView view, MotionEvent e)
{
final int index = e.getActionIndex();
final float[] coords = new float[] {
e.getX(index), e.getY(index)
};
Matrix matrix = new Matrix();
view.getImageMatrix().invert(matrix);
matrix.mapPoints(coords);
return coords;
}
Here is draw Method :
if i set bitmap image in draw, it does not fit the screen for every devices. If i set image with Display width and height, i am getting different co-ordinates.
#Override
public void draw(Canvas canvas) {
// TODO Auto-generated method stub
super.draw(canvas);
Resources res = getResources();
Drawable drawable = res.getDrawable(R.drawable.subimage);
mBitmap = ((BitmapDrawable) drawable).getBitmap();
canvas.drawBitmap(mBitmap, 0, 0, null);
}
Any Idea or help would be really helpful.
You have to calculate your device screen ratio first,
deviceWidth / screenHeight = ratio
then you have to multiply it with your desired coordinate :
ratio * xCoord = newXcoord; // and same for Y coord
By doing this you will keep the equivalent coordinates for all device sizes.
Also you may declare sizes and coordinates with respect to % of screen dimensions like :
x = 0.2 * deviceWidth // %20 of device width from left
Finally found some relative solution,Same Co-ordinates for all devices.Using Activity,no Custom ImageView.
On ImageView OnTouch ..
public boolean onTouch(View v, MotionEvent event) {
int action = event.getAction();
final int index = e.getActionIndex();
final float[] coords = new float[] {
e.getX(index), e.getY(index)
};
Matrix matrix = new Matrix();
choosenImageView.getImageMatrix().invert(matrix);
matrix.mapPoints(coords);
return true;
}
Draw Using Canvas
Resources res = getResources();
Drawable drawable = res.getDrawable(R.drawable.image);
Bitmap bmp= ((BitmapDrawable) drawable).getBitmap();
alteredBitmap = Bitmap.createBitmap(bmp.getWidth(), bmp.getHeight(), bmp.getConfig());
canvas = new Canvas(alteredBitmap);
paint = new Paint();
paint.setColor(Color.GREEN);
paint.setStrokeWidth(5);
matrix = new Matrix();
canvas.drawBitmap(bmp, matrix, paint);
You can try this
imageview.post(new Runnable() {
#Override
public void run() {
int[] posXY = new int[2];
imageview.getLocationOnScreen(posXY);
int MoveX = posXY[0];
int MoveY = posXY[1];
Log.i("xy co-ordinate", "x "+MoveX, "y"+MoveY);
}
});
I want to move the text over an image to fix the text on the desired place over the image.
I run this code successfully But its not optimum as its not user friendly.Text Movement doesn't match to finger's pick and drop even sometimes.If anybody have better code Please share with me or let me know if i am missing something.
//Listeners for the Canvas that is being awarded
popImgae.setOnTouchListener( new OnTouchListener(){
public boolean onTouch(View v, MotionEvent e) {
someGlobalXvariable = e.getX();
someGlobalYvariable = e.getY();
setTextPosition();
//saveImage(imgRecord.get(1),leftPos,topPos,popText.getTextSize(),popText.getText().toString());
return true;
}
});
public void setTextPosition(){
try {
redrawImage(imgRecord.get(1),Integer.parseInt(imgRecord.get(8)),imgRecord.get(6),Integer.parseInt(imgRecord.get(9)));
} catch (Exception e) {
// TODO: handle exception
System.out.println("##########Error in setTextPositio========="+e.getMessage());
}
}
///Redrawing the image & touchin Move of the Canvas with text
public void redrawImage(String path,float sizeValue,String textValue,int colorValue) {
//Bitmap bm = BitmapFactory.decodeResource(getResources(), R.drawable.fashion_pic);
BitmapFactory.Options options = new BitmapFactory.Options();
try {
options.inMutable = true;
} catch (Exception e) {
// TODO: handle exception
System.out.println("#############Error is======"+e.getMessage());
}
Bitmap bm = BitmapFactory.decodeFile(path,options);
//bm = imageManipulation.convertToMutable(bm);
proxy = Bitmap.createBitmap(bm.getWidth(), bm.getHeight(), Config.ARGB_8888);
Canvas c = new Canvas(proxy);
//Here, we draw the background image.
c.drawBitmap(bm, new Matrix(), null);
Paint paint = new Paint();
paint.setColor(colorValue); // Text Color
paint.setStrokeWidth(30); // Text Size
paint.setTextSize(sizeValue);
System.out.println("Values passing=========="+someGlobalXvariable+", "+someGlobalYvariable+", "
+sizeValue+", "+textValue);
//Here, we draw the text where the user last touched.
c.drawText(textValue, someGlobalXvariable, someGlobalYvariable, paint);
popImgae.setImageBitmap(proxy);
}
class MyView extends View{
public MyView(Context context) {
super(context);
//get your drawable image
setBackgroundDrawable(drawable);
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawText("text", x, y, new Paint());
}
float x,y;
#Override
public boolean onTouchEvent(MotionEvent event) {
x= event.getX();
y= event.getX();
invalidate();
return true;
}
}