imageView = (ImageView)findViewById(R.id.img);
imageView.setImageResource(R.drawable.aa);
// crash below into bitmap width and height > 0;
bitmap = Bitmap.createBitmap(imageView.getWidth(),imageView.getHeight(), Bitmap.Config.ARGB_8888);
canvas = new Canvas(bitmap);
// imageView.setImageBitmap(bitmap);
dw = imageView.getWidth();
dh = imageView.getHeight();
Log.e("bitmap", "bitmap" + imageView);
Log.e("canvas", "canvas" + canvas);
imageView.setOnTouchListener(this);
//imageView.setOnClickListener(this);
}
public boolean onTouch(View v, MotionEvent event) {
int action = event.getAction();
int x = (int) event.getX();
int y = (int) event.getY();
switch(action){
case MotionEvent.ACTION_DOWN:
if (x >= dh && x < (dh + bitmap.getWidth())
&& y >= dw && y < (dw + bitmap.getHeight())) {
}
break;
}
return true;
}
}
Replace code with below line when you got crash.
imageView.measure(0,0);
bitmap = Bitmap.createBitmap(imageView.getMeasuredWidth(),imageView.getMeasuredHeight(), Bitmap.Config.ARGB_8888);
Also:
dw = imageView.getMeasuredWidth();
dh = imageView.getMeasuredHeight();
Related
I have an app where I draw text on bitmap using the position specified by the user. When I ask canvas to draw the text using the x,y coordinates , the text draws in wrong place.
Where I position text Where it draws after I save
My code to save the image
private void drawText(Bitmap bitmap, TextView mText) {
try {
Resources resources = getResources();
android.graphics.Bitmap.Config bitmapConfig = bitmap.getConfig();
// set default bitmap config if none
if (bitmapConfig == null) {
bitmapConfig = android.graphics.Bitmap.Config.ARGB_8888;
}
// resource bitmaps are imutable,
// so we need to convert it to mutable one
bitmap = bitmap.copy(bitmapConfig, true);
Canvas canvas = new Canvas(bitmap);
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
paint.setColor(Color.WHITE);
paint.setTextSize(text.getTextSize());
Rect bounds = new Rect();
paint.getTextBounds(mText.getText().toString(), 0, mText.length(), bounds);
canvas.drawText(mText.getText().toString(), text.getX() , text.getY(), paint);
ImageView im = (ImageView) findViewById(R.id.imageView);
im.setImageBitmap(bitmap);
saveBitmap(bitmap);
} catch (Exception e) {
// TODO: handle exception
}
}
Code to drag textview
textView.setOnTouchListener(new View.OnTouchListener() {
int initialX = 0;
int initialY = 0;
#Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getActionMasked()) {
case MotionEvent.ACTION_DOWN:
initialX = (int) event.getX();
initialY = (int) event.getY();
break;
case MotionEvent.ACTION_MOVE:
int currentX = (int) event.getX();
int currentY = (int) event.getY();
RelativeLayout.LayoutParams lp = (RelativeLayout.LayoutParams) textView.getLayoutParams();
int left = lp.leftMargin + (currentX - initialX);
int top = lp.topMargin + (currentY - initialY);
int right = lp.rightMargin - (currentX - initialX);
int bottom = lp.bottomMargin - (currentY - initialY);
lp.rightMargin = right;
lp.leftMargin = left;
lp.bottomMargin = bottom;
lp.topMargin = top;
textView.setLayoutParams(lp);
break;
default:
break;
}
return true;
}
});
findViewById(R.id.save).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
drawText(getBitmap(), textView);
}
});
I want to draw a line on Imageview.for example when we select a particular text the text get colored under a line.this is my code.I am not able to see the line.and how to increase the width of this line
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_next);
imageView=(ImageView)findViewById(R.id.imageView1);
bitmap = getIntent().getExtras().getParcelable("name");
Display currentDisplay = getWindowManager().getDefaultDisplay();
float dw = currentDisplay.getWidth();
float dh = currentDisplay.getHeight();
//bitmap1 = Bitmap.createBitmap((int) dw, (int) dh,Bitmap.Config.ARGB_8888);
bitmap = bitmap.copy(Bitmap.Config.ARGB_8888, true);
canvas = new Canvas(bitmap);
paint = new Paint();
paint.setColor(Color.WHITE);
imageView.setImageBitmap(bitmap);
//for co-ordinate of the selected part of the image
imageView.setOnTouchListener(new OnTouchListener(){
#Override
public boolean onTouch(View v, MotionEvent event) {
int action = event.getAction();
x1 = (int) event.getX();
y1 = (int) event.getY();
x2 = (int) event.getX();
y2 = (int) event.getY();
switch(action){
case MotionEvent.ACTION_DOWN:
System.out.println("x1-cordinate"+x1+"y1-cordinate"+y1);
//startPt = projectXY((ImageView)v, bitmapMaster, x, y);
xstart=x1;
ystart=y1;
break;
/* case MotionEvent.ACTION_MOVE:
textSource.setText("ACTION_MOVE- " + x + " : " + y);
drawOnRectProjectedBitMap((ImageView)v, bitmapMaster, x, y);
break;*/
case MotionEvent.ACTION_UP:
System.out.println("x2-cordinate"+x2+"y2-cordinate"+y2);
canvas.drawLine(xstart, ystart, x2, y2, paint);
imageView.invalidate();
//drawOnRectProjectedBitMap((ImageView)v, bitmapMaster, x, y);
finalizeDrawing();
break;
}
/*
* Return 'true' to indicate that the event have been consumed.
* If auto-generated 'false', your code can detect ACTION_DOWN only,
* cannot detect ACTION_MOVE and ACTION_UP.
*/
return true;
}});`
I think you want something like this answer.
It will show like below
`
Button btnLoadImage;
TextView textSource, textInfo;
ImageView imageResult;
final int RQS_IMAGE1 = 1;
Uri source;
Bitmap bitmapMaster;
Canvas canvasMaster;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btnLoadImage = (Button)findViewById(R.id.loadimage);
textSource = (TextView)findViewById(R.id.sourceuri);
imageResult = (ImageView)findViewById(R.id.result);
btnLoadImage.setOnClickListener(new OnClickListener(){
#Override
public void onClick(View arg0) {
Intent intent = new Intent(Intent.ACTION_PICK,
android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(intent, RQS_IMAGE1);
}});
imageResult.setOnTouchListener(new OnTouchListener(){
#Override
public boolean onTouch(View v, MotionEvent event) {
int action = event.getAction();
int x = (int) event.getX();
int y = (int) event.getY();
switch(action){
case MotionEvent.ACTION_DOWN:
textSource.setText("ACTION_DOWN- " + x + " : " + y);
drawOnProjectedBitMap((ImageView)v, bitmapMaster, x, y);
break;
case MotionEvent.ACTION_MOVE:
textSource.setText("ACTION_MOVE- " + x + " : " + y);
drawOnProjectedBitMap((ImageView)v, bitmapMaster, x, y);
break;
case MotionEvent.ACTION_UP:
textSource.setText("ACTION_UP- " + x + " : " + y);
drawOnProjectedBitMap((ImageView)v, bitmapMaster, x, y);
break;
}
/*
* Return 'true' to indicate that the event have been consumed.
* If auto-generated 'false', your code can detect ACTION_DOWN only,
* cannot detect ACTION_MOVE and ACTION_UP.
*/
return true;
}});
}
/*
* Project position on ImageView to position on Bitmap
* draw on it
*/
private void drawOnProjectedBitMap(ImageView iv, Bitmap bm, int x, int y){
if(x<0 || y<0 || x > iv.getWidth() || y > iv.getHeight()){
//outside ImageView
return;
}else{
int projectedX = (int)((double)x * ((double)bm.getWidth()/(double)iv.getWidth()));
int projectedY = (int)((double)y * ((double)bm.getHeight()/(double)iv.getHeight()));
Paint paint = new Paint();
paint.setStyle(Paint.Style.FILL);
paint.setColor(Color.WHITE);
paint.setStrokeWidth(3);
canvasMaster.drawCircle(projectedX, projectedY, 5, paint);
imageResult.invalidate();
textSource.setText(x + ":" + y + "/" + iv.getWidth() + " : " + iv.getHeight() + "\n" +
projectedX + " : " + projectedY + "/" + bm.getWidth() + " : " + bm.getHeight()
);
}
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
Bitmap tempBitmap;
if(resultCode == RESULT_OK){
switch (requestCode){
case RQS_IMAGE1:
source = data.getData();
textSource.setText(source.toString());
try {
//tempBitmap is Immutable bitmap,
//cannot be passed to Canvas constructor
tempBitmap = BitmapFactory.decodeStream(
getContentResolver().openInputStream(source));
Config config;
if(tempBitmap.getConfig() != null){
config = tempBitmap.getConfig();
}else{
config = Config.ARGB_8888;
}
//bitmapMaster is Mutable bitmap
bitmapMaster = Bitmap.createBitmap(
tempBitmap.getWidth(),
tempBitmap.getHeight(),
config);
canvasMaster = new Canvas(bitmapMaster);
canvasMaster.drawBitmap(tempBitmap, 0, 0, null);
imageResult.setImageBitmap(bitmapMaster);
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
break;
}
}
}
}`free draw on bitmap followed this link and now I am able to draw the line above the ImageView
I am trying to get the color of the spot where I touched on an ImageView. And I succeeded using getPixel(x,y) for getting the color, but on another spot I am not getting the color of the pixel where I touched; I am getting the color of a different pixel.
ImageView xml:
<ImageView
android:id="#+id/ImgSelected"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:contentDescription="#string/todo" />
Assigning Bitmap to ImageView:
imageViewSelected.setScaleType(ImageView.ScaleType.CENTER_INSIDE);
imageViewSelected.setImageBitmap(bm2);
OnTouch() for getting the pixel
#Override
public boolean onTouchEvent(MotionEvent event) {
if (imageViewSelected.getVisibility() == 0) {
float eventX = event.getX();
float eventY = event.getY();
float[] eventXY = new float[] { eventX, eventY };
Matrix invertMatrix = new Matrix();
imageViewSelected.getImageMatrix().invert(invertMatrix);
invertMatrix.mapPoints(eventXY);
int x = Integer.valueOf((int) eventXY[0]);
int y = Integer.valueOf((int) eventXY[1]);
Drawable imgDrawable = imageViewSelected.getDrawable();
Bitmap bitmap = ((BitmapDrawable) imgDrawable).getBitmap();
// Limit x, y range within bitmap
if (x < 0) {
x = 0;
} else if (x > bitmap.getWidth() - 1) {
x = bitmap.getWidth() - 1;
}
if (y < 0) {
y = 0;
} else if (y > bitmap.getHeight() - 1) {
y = bitmap.getHeight() - 1;
}
int touchedRGB = bitmap.getPixel(x, y);
ImgColorPublic.touchX = (int) event.getX();
ImgColorPublic.touchY = (int) event.getY();
ImgColorPublic.touchColor = Integer.toHexString(touchedRGB);
}
return false;
}
Using this code, for some images I am getting the correct value, but not for all images.
So I have an ImageView to which I have set an OnTouchListener. The OnTouch method is shown below.
//Touch event related variables
int touchState;
final int IDLE = 0;
final int TOUCH = 1;
final int PINCH = 2;
float dist0, distCurrent;
public boolean onTouch(View view, MotionEvent event) {
boolean handledHere = false;
float distx, disty;
final int action = event.getAction();
switch(action & MotionEvent.ACTION_MASK){
case MotionEvent.ACTION_DOWN:
//A pressed gesture has started, the motion contains the initial starting location.
touchState = TOUCH;
break;
case MotionEvent.ACTION_POINTER_DOWN:
//A non-primary pointer has gone down.
touchState = PINCH;
//Get the distance when the second pointer touch
distx = event.getX(0) - event.getX(1);
disty = event.getY(0) - event.getY(1);
dist0 = FloatMath.sqrt(distx * distx + disty * disty);
break;
case MotionEvent.ACTION_MOVE:
if(touchState == PINCH){
//Get the current distance
distx = event.getX(0) - event.getX(1);
disty = event.getY(0) - event.getY(1);
distCurrent = FloatMath.sqrt(distx * distx + disty * disty);
drawMatrix((ImageView) view);
} else {
handledHere = startDrag (view);
}
break;
case MotionEvent.ACTION_UP:
//A pressed gesture has finished.
touchState = IDLE;
break;
case MotionEvent.ACTION_POINTER_UP:
//A non-primary pointer has gone up.
touchState = TOUCH;
break;
}
return handledHere;
}
private void drawMatrix(ImageView view){
float curScale = distCurrent/dist0;
if (curScale < 0.5){
curScale = 0.5f;
} else if (curScale > 1.5){
curScale = 1.2f;
}
Bitmap originalBitmap = Bitmap.createBitmap(view.getWidth(), view.getHeight(), Bitmap.Config.ARGB_8888); //view.getDrawingCache();
Canvas canvas = new Canvas(originalBitmap);
view.draw(canvas);
int[] originalSize = (int[]) view.getTag();
int newHeight = (int) (originalSize[1] * curScale);
int newWidth = (int) (originalSize[0] * curScale);
view.setImageBitmap(getResizedBitmap(originalBitmap, newHeight, newWidth));
view.getLayoutParams().height=newHeight;
view.getLayoutParams().width=newWidth;
}
private Bitmap getResizedBitmap(Bitmap bm, int newHeight, int newWidth) {
int width = bm.getWidth();
int height = bm.getHeight();
float scaleWidth = ((float) newWidth) / width;
float scaleHeight = ((float) newHeight) / height;
// create a matrix for the manipulation
Matrix matrix = new Matrix();
// resize the bit map
matrix.postScale(scaleWidth, scaleHeight);
// recreate the new Bitmap
Bitmap resizedBitmap = Bitmap.createBitmap(bm, 0, 0, width, height, matrix, false);
return resizedBitmap;
}
The thing is, when I zoom in or out using finger gesture, the quality of the image deteriorates. For example, if the image is a PNG one, with a semi-transparent gradient, the gradient will become a solid blurred color, and the rest of the image becomes pixelated... Anybody has a solution for this, or come across the same problem?
In getResizedBitmap() add filtering:
Bitmap resizedBitmap = Bitmap.createBitmap(bm, 0, 0, width, height, matrix, true);
#Override protected void onDraw(Canvas canvas) {
//canvas.drawPicture();
canvas.drawColor(Color.CYAN);
Paint p= new Paint();
p.setColor(Color.RED);
p.setStrokeWidth(20);
canvas.drawLine(100, 200, 400, 500, p);
if(movingObjects.size() > 0){
for (MovingObject ball : movingObjects) {
canvas.drawBitmap(ball.getBitmap(), ball.getX(), ball.getY(), null);
}
}
}
public boolean onTouchEvent(MotionEvent event) {
int eventaction = event.getAction();
int X = (int)event.getX();
int Y = (int)event.getY();
boolean redraw = false;
switch (eventaction ) {
case MotionEvent.ACTION_DOWN:
currentMovingObjectId = 0;
for (MovingObject movingObject : movingObjects) {
int topLeftX = movingObject.getX() ;
int topLeftY = movingObject.getY() ;
double imageSize = movingObject.getSize();
double radCircle = Math.sqrt( (double) (((topLeftX-X)*(topLeftX-X)) + (topLeftY-Y)*(topLeftY-Y)));
if ( (radCircle < imageSize) &&
(X- topLeftX) < movingObject.getWidth() && (Y - topLeftY) < movingObject.getHeight() &&
(X- topLeftX) > 0 && (Y- topLeftY) > 0){
currentMovingObjectId = movingObjects.indexOf(movingObject) + 1;
offsetX = X- topLeftX;
offsetY = Y - topLeftY;
redraw = true;
break;
}
}
break;
case MotionEvent.ACTION_MOVE:
if ( currentMovingObjectId > 0) {
drawAtX = X - offsetX;
drawAtY = Y - offsetY;
if(drawAtX < 0 || (drawAtX + movingObjects.get(currentMovingObjectId-1).getWidth()) > MovingObject.screenWidth)
drawAtX = movingObjects.get(currentMovingObjectId-1).getX();
if(drawAtY < 0 || (drawAtY + movingObjects.get(currentMovingObjectId-1).getHeight()) > MovingObject.screenHeight)
drawAtY = movingObjects.get(currentMovingObjectId-1).getY();
if(drawAtX != movingObjects.get(currentMovingObjectId-1).getX() || drawAtY != movingObjects.get(currentMovingObjectId-1).getY()){
movingObjects.get(currentMovingObjectId-1).setX(drawAtX);
movingObjects.get(currentMovingObjectId-1).setY(drawAtY);
redraw = true;
}
}
break;
case MotionEvent.ACTION_UP:
break;
}
if(redraw)
invalidate();
return true;
}
The above code describes the onTouch and onDraw method in my custom view class and i have to prevent image cross the line.As we can implement using matrix where we can move the object horizontal and vertical avoiding the object by setting the wall on 4 sides of cell but i have to move object freely inside a puzzle.Any logic would be helpful i am stuck.Thanks in advance