Android, Attaching e-signature on pdf using drag and drop - android

I'm developing an Android application, I need to implement placing user signature(image) on pdf draging by user. I'm using pdf viewer(com.github.barteksc.pdfviewer.PDFView) to show pdf and I'm using drag and drop listener to get coordinates from view. but it is not placing in proper position on pdf. I spent lot of time on other solutions, but there is no help. (or please suggest any free SDK available in Android to achieve the same.)
Please help me resolve this. Here is my code sample.
public class MainActivity extends AppCompatActivity implements View.OnTouchListener, View.OnDragListener, OnPageChangeListener, OnPageScrollListener {
private PDFView pdfViewDemo;
private Button buttonGetPage;
private ImageView imageViewDemo;
private ImageView imageDrag;
private String pdfUrl = "/sdcard/sample.pdf";
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_pdf_view);
findViewById(R.id.rootView).setOnDragListener(this);
pdfViewDemo = findViewById(R.id.pdfView);
final File file = new File(pdfUrl);
pdfViewDemo.setMaxZoom(0);
pdfViewDemo.fromFile(file)
.onPageChange(this)
.onPageScroll(this)
.spacing(10)
.swipeHorizontal(true)
.enableDoubletap(false)
.load();
//Implementation of Drag and Drop---------------------------------------------
imageDrag = findViewById(R.id.imageDrag);
imageDrag.setOnTouchListener(this);
//Implementation of Drag and Drop---------------------------------------------
imageViewDemo = findViewById(R.id.imageDemo);
buttonGetPage = findViewById(R.id.buttonGetPage);
buttonGetPage.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
ArrayList<Bitmap> bitmaps = pdfToBitmap(file);
pdfViewDemo.setVisibility(View.GONE);
imageViewDemo.setVisibility(View.VISIBLE);
imageViewDemo.setImageBitmap(bitmaps.get(0));
Log.e("test", "Bitmaps: " + bitmaps.size());
}
});
}
private ArrayList<Bitmap> pdfToBitmap(File pdfFile) {
ArrayList<Bitmap> bitmaps = new ArrayList<>();
try {
PdfRenderer renderer = new PdfRenderer(ParcelFileDescriptor.open(pdfFile, ParcelFileDescriptor.MODE_READ_ONLY));
Bitmap bitmap;
final int pageCount = renderer.getPageCount();
for (int i = 0; i < pageCount; i++) {
PdfRenderer.Page page = renderer.openPage(i);
int width = getResources().getDisplayMetrics().densityDpi / 72 * page.getWidth();
int height = getResources().getDisplayMetrics().densityDpi / 72 * page.getHeight();
bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
page.render(bitmap, null, null, PdfRenderer.Page.RENDER_MODE_FOR_DISPLAY);
bitmaps.add(bitmap);
// close the page
page.close();
}
// close the renderer
renderer.close();
} catch (Exception ex) {
ex.printStackTrace();
}
return bitmaps;
}
#Override
public void onPageChanged(int page, int pageCount) {
Log.e("test", "onPageChanged() called with: page = [" + page + "], pageCount = [" + pageCount + "]");
}
#Override
public void onPointerCaptureChanged(boolean hasCapture) {
Log.e("test", "onPointerCaptureChanged() called with: hasCapture = [" + hasCapture + "]");
}
#Override
public void onPageScrolled(int page, float positionOffset) {
Log.e("test", "onPageScrolled() called with: page = [" + page + "], positionOffset = [" + positionOffset + "]");
}
#Override
public boolean onTouch(View view, MotionEvent event) {
Log.e("test", "onTouch() called with: v = [" + view + "], event = [" + event + "]");
if (event.getAction() == MotionEvent.ACTION_DOWN) {
View.DragShadowBuilder shadowBuilder = new View.DragShadowBuilder(view);
view.startDrag(null, shadowBuilder, view, 0);
return true;
} else {
return false;
}
}
#Override
public boolean onDrag(View v, DragEvent event) {
int action = event.getAction();
switch (action) {
case DragEvent.ACTION_DRAG_STARTED:
Log.e("test", "onDrag: ACTION_DRAG_STARTED");
break;
case DragEvent.ACTION_DRAG_ENTERED:
Log.e("test", "onDrag: ACTION_DRAG_ENTERED");
break;
case DragEvent.ACTION_DRAG_EXITED:
Log.e("test", "onDrag: ACTION_DRAG_EXITED");
break;
case DragEvent.ACTION_DROP:
Log.e("test", "onDrag: ACTION_DROP");
Log.e("test-", "X: " + (int) event.getX());
Log.e("test-", "Y: " + (int) event.getY());
getPdfCoordinates((int) event.getX(), (int) event.getY());
/*View tvState = (View) event.getLocalState();
val tvParent = tvState.parent as ViewGroup
tvParent.removeView(tvState)
val container = view as LinearLayout
container.addView(tvState)
tvParent.removeView(tvState)
tvState.x = dragEvent.x
tvState.y = dragEvent.y
view.addView(tvState)
view.setVisibility(View.VISIBLE)
int x = (int) v.getX();
int y = (int) v.getY();
RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(x, y);
textTitle.setLayoutParams(layoutParams);*/
break;
case DragEvent.ACTION_DRAG_ENDED:
Log.e("test", "onDrag: ACTION_DRAG_ENDED" + v.getX() + ":" + v.getY());
imageDrag.setVisibility(View.VISIBLE);
break;
default:
break;
}
return true;
}
private void getPdfCoordinates(int x, int y) {
Log.e("test-", "PDF: getMeasuredWidth: " + pdfViewDemo.getMeasuredWidth());
Log.e("test-", "PDF: getWidth: " + pdfViewDemo.getWidth());
Log.e("test-", "PDF: getOptimalPageHeight: " + pdfViewDemo.getOptimalPageHeight());
Log.e("test-", "PDF: getOptimalPageWidth: " + pdfViewDemo.getOptimalPageWidth());
Log.e("test-", "PDF: getMeasuredWidthAndState: " + pdfViewDemo.getMeasuredWidthAndState());
Log.e("test-", "PDF: getMinimumHeight: " + pdfViewDemo.getMinimumHeight());
Log.e("test-", "PDF: getMinimumWidth: " + pdfViewDemo.getMinimumWidth());
x= (int) pdfViewDemo.getOptimalPageHeight()/2-x;
y=(int)pdfViewDemo.getOptimalPageWidth()/2-y;
addImageToPdf(x, y);
}
private void addImageToPdf(int x, int y) {
Log.e("test", "addImageToPdf() called with: x = [" + x + "], y = [" + y + "]" + pdfViewDemo.getCurrentPage());
try {
PdfReader reader = new PdfReader(pdfUrl);
PdfStamper stamper = new PdfStamper(reader, new FileOutputStream("/sdcard/test_pdf.pdf"));
PdfContentByte content = stamper.getOverContent(pdfViewDemo.getCurrentPage()+1);
com.itextpdf.text.Image image = Image.getInstance("/sdcard/sign_1.jpg");
image.scaleAbsoluteHeight(50);
image.scaleAbsoluteWidth((image.getWidth() * 50) / image.getHeight());
image.setAbsolutePosition(y, x);
content.addImage(image);
stamper.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
Here are the screenshots of input and output

According to this answer, the coordinates of a given page can be anything and must be checked using the PdfReader.
There may also be a handful of other factors influencing the positioning.
PDF coordinate system may be scaled differently than androids.
PdfStamper may place stamp in an unexpected way (I could not find sufficient documentation) thus some testing is required to find out where exactly the stamp is placed for given coordinates.
The coordinates of the touch event which you are intercepting at the drop are absolute but should be relative to the position of the PdfView. This can be achieved getting the absolute position of the PdfView and subtracting it from the TouchEvent coordinates.
Just a few thoughts to help with your debugging.

Related

Seekbar change progress ONLY when dragging Thumb

I'm facing an issue on how to control Seekbar progress when user ONLY touching the Thumb
I knew it is a duplicated question but here are the links that gave me an idea about it this and this.
After several rounds of testing, below are my working logic result
mySeekbar.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
Rect rcThumb = mySeekbar.getThumb().getBounds();
int iWidth = rcThumb.width();
if (event.getX() >= (rcThumb.left - iWidth) && event.getX() <= (rcThumb.right + iWidth)) {
return false;
} else
return true;
}
});
Expected result
no drag or tap
during drag or tap
Problem
You can just copy and paste the above code for testing. As we know that when touching or dragging the thumb will be larger, but there is an issue were thumb will be large when not touching it. This issue will not happen often but seldom. Anyway to solve this ? Much help is appreciated.
Problem result
no drag or tap
during drag or tap
After few rounds of testing, I was able to accomplish the result. Cheers :)
private boolean mIsDragging;
private boolean isWithinThumb(MotionEvent event, SeekBar seekBar) {
Rect rcThumb = seekBar.getThumb().getBounds();
Rect rcDetectTouchArea = new Rect();
int iWidth = rcThumb.width();
int iHeight = rcThumb.height();
rcDetectTouchArea.left = rcThumb.left - iWidth;
rcDetectTouchArea.right = rcThumb.right + iWidth;
rcDetectTouchArea.bottom = rcThumb.bottom + iHeight;
Log.i("TAG", "rcDetectSize.left = " + rcDetectTouchArea.left + " | rcDetectSize.right = " + rcDetectTouchArea.right + " | rcDetectSize.bottom = " + rcDetectTouchArea.bottom + " | event.getX()= " + event.getX() + " | event.getY()= " + event.getY() + " | rcThumb area = " + rcDetectTouchArea.contains((int) event.getX(), (int) event.getY()));
return rcDetectTouchArea.contains((int) event.getX(), (int) event.getY());
}
mSbTest.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
if (isWithinThumb(event, mSbTest)) {
mIsDragging = true;
return false;
}
case MotionEvent.ACTION_UP:
if (mIsDragging) {
mIsDragging = false;
return false;
}
if (isWithinThumb(event, mSbTest)) {
return false;
} else {
return true;
}
case MotionEvent.ACTION_MOVE:
if (!mIsDragging) {
return true;
}
}
return onTouchEvent(event);
}
});

how to determine width and height of rectangle drawn on bitmap in a imageview

this is the code i am using to get starting x,y coordinates. i also need width and height of rectangle drawn.
this code i have taken from a website link- http://android-er.blogspot.in/2013/09/detect-touch-and-draw-rect-on-bitmap.html
please provide solution
public class MainActivity extends Activity {
Button btnLoadImage;
TextView textSource;
ImageView imageResult, imageDrawingPane;
final int RQS_IMAGE1 = 1;
Uri source;
Bitmap bitmapMaster;
Canvas canvasMaster;
Bitmap bitmapDrawingPane;
Canvas canvasDrawingPane;
projectPt startPt;
projectPt endpt;
#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);
imageDrawingPane = (ImageView)findViewById(R.id.drawingpane);
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);
startPt = projectXY((ImageView)v, bitmapMaster, x, y);
break;
case MotionEvent.ACTION_MOVE:
textSource.setText("ACTION_MOVE- " + x + " : " + y);
drawOnRectProjectedBitMap((ImageView)v, bitmapMaster, x, y);
break;
case MotionEvent.ACTION_UP:
textSource.setText("ACTION_UP- " + x + " : " + y);
drawOnRectProjectedBitMap((ImageView)v, bitmapMaster, x, y);
finalizeDrawing();
break;
}
return true;
}});
}
class projectPt{
int x;
int y;
projectPt(int tx, int ty){
x = tx;
y = ty;
}
}
private projectPt projectXY(ImageView iv, Bitmap bm, int x, int y){
if(x<0 || y<0 || x > iv.getWidth() || y > iv.getHeight()){
//outside ImageView
return null;
}else{
int projectedX = (int)((double)x * ((double)bm.getWidth()/(double)iv.getWidth()));
int projectedY = (int)((double)y * ((double)bm.getHeight()/(double)iv.getHeight()));
return new projectPt(projectedX, projectedY);
}
}
private void drawOnRectProjectedBitMap(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()));
//clear canvasDrawingPane
canvasDrawingPane.drawColor(Color.TRANSPARENT, Mode.CLEAR);
Paint paint = new Paint();
paint.setStyle(Paint.Style.STROKE);
paint.setColor(Color.WHITE);
paint.setStrokeWidth(4);
canvasDrawingPane.drawRect(startPt.x, startPt.y, projectedX, projectedY, paint);
imageDrawingPane.invalidate();
// textSource.setText(x + ":" + y + "/" + iv.getWidth() + " : " + iv.getHeight() + "\n" +
// projectedX + " : " + projectedY + "/" + bm.getWidth() + " : " + bm.getHeight()
textSource.setText(startPt.x + ":" + startPt.y + "/" + iv.getWidth() + " : " + iv.getHeight() + "\n" +
projectedX + " : " + projectedY+ "/" + bm.getWidth() + " : " + bm.getHeight()
);
}
}
private void finalizeDrawing(){
canvasMaster.drawBitmap(bitmapDrawingPane, 0, 0, null);
}
#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 = BitmapFactory.decodeStream(
getContentResolver().openInputStream(source));
Config config;
if(tempBitmap.getConfig() != null){
config = tempBitmap.getConfig();
}else{
config = Config.ARGB_8888;
}
bitmapMaster = Bitmap.createBitmap(
tempBitmap.getWidth(),
tempBitmap.getHeight(),
config);
canvasMaster = new Canvas(bitmapMaster);
canvasMaster.drawBitmap(tempBitmap, 0, 0, null);
imageResult.setImageBitmap(bitmapMaster);
bitmapDrawingPane = Bitmap.createBitmap(
tempBitmap.getWidth(),
tempBitmap.getHeight(),
config);
canvasDrawingPane = new Canvas(bitmapDrawingPane);
imageDrawingPane.setImageBitmap(bitmapDrawingPane);
}
catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
break;
}
}
}
}
Before drawing
Rect rect = new Rect(startPt.x, startPt.y, projectedX, projectedY);
canvasDrawingPane.drawRect(rect,paint);
width = rect.width();
height = rect.height();
imageDrawingPane.invalidate();
Here is your answer.
Here int projectedX and int int projectedY contains width and height of rectangle drawn.
You can make both global and access anywhere in the class.
Like this..
//rectangle width and height
int projectedX;
int projectedY;
//end
Button btnLoadImage;
TextView textSource;
ImageView imageResult, imageDrawingPane;
Now access projectedX & projectedY to get width and height anywhere.

Play two sound together on two button touch using soundpool

I am trying to play two sound together when two button is touch together at the same time. I have button1 and button2, while button1 is touch, button2 wont play the sound. But when I put my finger off button1 then touching button2 plays the sound.
I have tried googling around but couldn't find an answer.
What I wanted to do is clear. Play two sound together when two buttons are touch together.
Below is my code so far.
public class MultitouchtestActivity extends MultiTouchActivity {
/** Called when the activity is first created. */
private Button btn1;
private Button btn2;
SoundPool soundPool;
AudioManager audioManager;
int soundId;
int kID, sID;
#Override
public void onCreate(Bundle savedInstanceState)
{
this.requestWindowFeature(Window.FEATURE_NO_TITLE);
this.getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
this.getWindow().clearFlags(
WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN);
super.onCreate(savedInstanceState);
audioManager = (AudioManager)getSystemService(Context.AUDIO_SERVICE);
setContentView(R.layout.main);
btn1 = (Button) findViewById(R.id.button1);
btn2 = (Button) findViewById(R.id.button2);
//the maximum number of simultaneous streams for this SoundPool object
int maxStreams = 4;
//the audio stream type as described in AudioManager
int streamType = AudioManager.STREAM_MUSIC;
//the sample-rate converter quality. Currently has no effect. Use 0 for the default.
int srcQuality = 0;
soundPool = new SoundPool(maxStreams, streamType, srcQuality);
soundPool.setOnLoadCompleteListener(soundPoolOnLoadCompleteListener);
soundId = soundPool.load(this, R.raw.c, 1);
kID = soundPool.load(this, R.raw.k, 1);
sID = soundPool.load(this, R.raw.s, 1);
btn1.setOnTouchListener(new View.OnTouchListener()
{
public boolean onTouch(View v, MotionEvent event)
{
if(event.getAction() == MotionEvent.ACTION_DOWN)
{
float vol = audioManager.getStreamVolume(
AudioManager.STREAM_MUSIC);
float maxVol = audioManager.getStreamMaxVolume(
AudioManager.STREAM_MUSIC);
float leftVolume = vol/maxVol;
float rightVolume = vol/maxVol;
int priority = 1;
int no_loop = 0;
float normal_playback_rate = 1f;
soundPool.play(kID,
leftVolume,
rightVolume,
priority,
no_loop,
normal_playback_rate);
return true;
}
return false;
}
});
btn2.setOnTouchListener(new View.OnTouchListener()
{
public boolean onTouch(View v, MotionEvent event)
{
if(event.getAction() == MotionEvent.ACTION_DOWN)
{
float vol = audioManager.getStreamVolume(
AudioManager.STREAM_MUSIC);
float maxVol = audioManager.getStreamMaxVolume(
AudioManager.STREAM_MUSIC);
float leftVolume = vol/maxVol;
float rightVolume = vol/maxVol;
int priority = 1;
int no_loop = 0;
float normal_playback_rate = 1f;
soundPool.play(sID,
leftVolume,
rightVolume,
priority,
no_loop,
normal_playback_rate);
return true;
}
return false;
}
});
}
SoundPool.OnLoadCompleteListener soundPoolOnLoadCompleteListener = new SoundPool.OnLoadCompleteListener()
{
#Override
public void onLoadComplete(SoundPool soundPool, int sampleId, int status)
{
if(status==0)
{
btn1.setEnabled(true);
btn2.setEnabled(true);
}
else
{
Toast.makeText(MultitouchtestActivity.this,"SoundPool.load() fail", Toast.LENGTH_LONG).show();
}
}
};
}
public class MultiTouchActivity extends Activity implements OnTouchListener {
private View parent;
public void onCreate(Bundle instance)
{
super.onCreate(instance);
parent = findViewById(android.R.id.content).getRootView();
parent.setOnTouchListener(this);
}
public boolean onTouch(View v, MotionEvent event) {
for (int ptrIndex = 0; ptrIndex < event.getPointerCount(); ptrIndex++) {
// index of the pointer which starts this Event
int actionPointerIndex = event.getActionIndex();
// resolve the action as a basic type (up, down or move)
int actionResolved = event.getAction() & MotionEvent.ACTION_MASK;
if (actionResolved < 7 && actionResolved > 4) {
actionResolved = actionResolved - 5;
}
if (actionResolved == MotionEvent.ACTION_MOVE) {
dealEvent(ptrIndex, event, v, actionResolved);
Log.v("tag", "move" + ptrIndex);
} else {
dealEvent(actionPointerIndex, event, v, actionResolved);
}
}
return false;
}
private void dealEvent(int actionPointerIndex, MotionEvent event,
View eventView, int actionresolved) {
int rawX, rawY;
int location[] = { 0, 0 };
eventView.getLocationOnScreen(location);
// Log.v("tag", location + "");
rawX = (int) event.getX(actionPointerIndex) + location[0];
rawY = (int) event.getY(actionPointerIndex) + location[1];
ArrayList<View> views = getTouchedViews(rawX, rawY, actionresolved);
// dumpEvent(event);
for (View view : views) {
int x, y;
view.getLocationOnScreen(location);
x = rawX - location[0];
y = rawY - location[1];
// Log.v("tag", "touched" + view.toString());
/*
* view.onTouchEvent(MotionEvent.obtain(event.getDownTime(),
* event.getEventTime(), event.getActionMasked(), x, y,
* event.getMetaState()));
*/
// MotionEvent me = MotionEvent.obtain(event);
MotionEvent me = MotionEvent.obtain(event.getDownTime(),
event.getEventTime(), actionresolved, x, y,
event.getPressure(actionPointerIndex),
event.getPressure(actionPointerIndex),
event.getMetaState(), event.getXPrecision(),
event.getYPrecision(), event.getDeviceId(),
event.getEdgeFlags());
me.setLocation(x, y);
// Log.v("tag", "oldeventid: " + event.getAction() + " #" +
// actionPointerIndex+ " id" + ptrId+ " resolved "+ actionResolved);
// Log.v("tag", "neweventid: " + me.getAction() + " #" +
// actionPointerIndex+ " id" + ptrId+ " resolved "+ actionResolved);
if (!me.equals(event)) {
/*
* Log.v("tag", "actionindex: " + actionPointerIndex +
* " resolved: " + actionPointerIndex + " to " + view.toString()
* + " y:" + view.getTop() + "-" + (view.getTop() +
* view.getHeight()));
*/
// me.setAction(actionresolved);
view.onTouchEvent(me);
}
if (actionresolved == MotionEvent.ACTION_MOVE) {
Log.v("tag",
"#" + actionPointerIndex + "Rawx:" + rawX + " rawy:"
+ rawY + "x:" + x + " y:" + y + " "
+ view.toString());
}
}
}
private ArrayList<View> getTouchedViews(int x, int y, int action) {
int moveGap = 0;
if (action == MotionEvent.ACTION_MOVE) {
moveGap = 0;
}
ArrayList<View> touchedViews = new ArrayList<View>();
ArrayList<View> possibleViews = new ArrayList<View>();
if (parent instanceof ViewGroup) {
possibleViews.add(parent);
for (int i = 0; i < possibleViews.size(); i++) {
View view = possibleViews.get(i);
int location[] = { 0, 0 };
view.getLocationOnScreen(location);
if (((view.getHeight() + location[1] + moveGap >= y)
& (view.getWidth() + location[0] + moveGap >= x)
& (view.getLeft() - moveGap <= x) & (view.getTop()
- moveGap <= y))
|| view instanceof FrameLayout) {
touchedViews.add(view);
possibleViews.addAll(getChildViews(view));
}
}
}
return touchedViews;
}
private ArrayList<View> getChildViews(View view) {
ArrayList<View> views = new ArrayList<View>();
if (view instanceof ViewGroup) {
ViewGroup v = ((ViewGroup) view);
if (v.getChildCount() > 0) {
for (int i = 0; i < v.getChildCount(); i++) {
views.add(v.getChildAt(i));
}
}
}
return views;
}
}

Line is not drawing on Imageview in android

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

Drag & Drop for older Android not precise

So I'm attempting to make a "magnetic poetry" type application. Users will move various Button widgets on the screen. I am using a Button widget since it is the closest to the look of the magnet, though I am open to other options!
The objects are not properly moving with my finger. They're close but they're not exactly in line with my finger. The X coordinate on my phone seems to be fine, but the Y corrdinate is off. Is this perhaps due to the title bar?
private final static int DRAGGING_OFF = 0;
private final static int DRAGGING_ON = 1;
private int dragStatus;
private GestureDetector mGestureDetector;
private int mOffsetX;
private int mOffsetY;
private LayoutParams mOldParams;
private RelativeLayout.LayoutParams lp;
#Override
public boolean onTouchEvent(MotionEvent event) {
if(!mGestureDetector.onTouchEvent(event)) {
if(event.getAction() == MotionEvent.ACTION_MOVE) {
if(dragStatus == DRAGGING_ON) {
Log.e(VIEW_LOG_TAG, "Dragging! RAW -- " + event.getRawX() + " : " + event.getRawY() + " NOT RAW -- " + event.getX() + " : " + event.getY());
int rawX, rawY;
int finalX, finalY;
rawX = (int) event.getRawX();
rawY = (int) event.getRawY();
finalX = rawX - mOffsetX;
finalY = rawY - mOffsetY;
lp.setMargins(finalX, finalY, 0, 0);
this.setLayoutParams(lp);
}
return true;
} else if(event.getAction() == MotionEvent.ACTION_UP) {
if(dragStatus == DRAGGING_ON) {
dragStatus = DRAGGING_OFF;
Log.e(VIEW_LOG_TAG, "Stopped dragging!");
}
return true;
} else {
return super.onTouchEvent(event);
}
} else {
return true;
}
}
private final GestureDetector.SimpleOnGestureListener mListener = new GestureDetector.SimpleOnGestureListener() {
#Override
public boolean onDown(MotionEvent e) {
int[] location = new int[2];
Log.e(VIEW_LOG_TAG, "Down! RAW -- " + e.getRawX() + " : " + e.getRawY() + " NOT RAW -- " + e.getX() + " : " + e.getY());
dragStatus = DRAGGING_ON;
// Sets the current location of the View in the int[] passed to it; x then y.
getLocationInWindow(location);
Log.e(VIEW_LOG_TAG, "Down location: " + location[0] + " " + location[1]);
mOffsetX = (int) e.getRawX() - location[0];
mOffsetY = (int) e.getRawY() - location[1];
mOldParams = getLayoutParams();
return true;
}
};
I think the issue is that you're not getting the DELTA of the current touch point Y and the cached, last touch point y. You need something like this:
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
final TextView textView = (TextView) findViewById(R.id.text);
final ImageView image = (ImageView) findViewById(R.id.image);
matrix.setTranslate(1f, 1f);
image.setImageMatrix(matrix);
image.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
matrix.getValues(m); //copy matrix values into array
PointF currentXYTouchPoint = new PointF(event.getX(), event.getY());
switch(event.getAction()) {
case MotionEvent.ACTION_DOWN: //start of pressed gesture
lastXYTouchPoint.set(event.getX(), event.getY()); //save the last touchpoint
mode = DRAG;
break;
case MotionEvent.ACTION_MOVE:
//calculate the change in finger position
float deltaX = currentXYTouchPoint.x - lastXYTouchPoint.x;
float deltaY = currentXYTouchPoint.y - lastXYTouchPoint.y;
matrix.postTranslate(deltaX, deltaY); //move the entire image by the deltas
image.setImageMatrix(matrix);
// save this last starting touchpoint
lastXYTouchPoint.set(currentXYTouchPoint.x, currentXYTouchPoint.y);
break;
}
textView.setText("TouchPoint started at " + currentXYTouchPoint.x + ", " + currentXYTouchPoint.y + " & the matrix is now " + Arrays.toString(m));
return true;
}
});
}
Adapt it to your own purposes, but the basic idea is there.

Categories

Resources