programacion - Android: cómo obtener la posición x/y del borde de la imagen dentro de la vista de imagen
programacion android pdf 2018 (4)
Aquí hay un método que quería compartir, que devolverá el desplazamiento del mapa de bits dentro de una imageView usando getImageMatrix
public static int[] getBitmapOffset(ImageView img, Boolean includeLayout) {
int[] offset = new int[2];
float[] values = new float[9];
Matrix m = img.getImageMatrix();
m.getValues(values);
offset[0] = (int) values[5];
offset[1] = (int) values[2];
if (includeLayout) {
ViewGroup.MarginLayoutParams lp = (ViewGroup.MarginLayoutParams) img.getLayoutParams();
int paddingTop = (int) (img.getPaddingTop() );
int paddingLeft = (int) (img.getPaddingLeft() );
offset[0] += paddingTop + lp.topMargin;
offset[1] += paddingLeft + lp.leftMargin;
}
return offset;
}
Si tengo un ImageView que llena la pantalla.
El fondo de ImageView se establece en color verde.
Coloco un mapa de bits en el ImageView, manteniendo proporciones de mapa de bits.
Una foto de retrato en este diseño mostrará verde en ambos lados, izquierdo y derecho
(Orientación del teléfono = retrato).
Ahora, ¿Cómo obtengo la posición x / y del lado izquierdo del borde cuando el verde termina y comienza el mapa de bits?
El fondo para este proyecto de esfuerzo es que quiero escribir texto en la imagen y guardar la imagen en una nueva imagen con el texto. El problema es..
Desde que escala la imagen enSampleSize = 4; y el ImageView lo reduce aún más, al guardar esta nueva imagen se obtendrá una pequeña imagen de aproximadamente 250x350.
Lo que quiero es usar las posiciones x / y y transferir el texto escrito a la imagen original inSampleSize = 4 o a la imagen sdcard 1500x3000
Sé y leí otras preguntas sobre esto que tengo que "Hacer los cálculos matemáticos" yo solo necesito esta pequeña respuesta.
Olvidé que puedo tomar una captura de pantalla para aclarar.
así es como se ve: (Me sale un nuevo bolígrafo al presionar el botón "bolígrafo", cada bolígrafo tiene su propio texto y posición únicos en la pantalla
Aquí está la imagen vista
import java.util.HashMap;
import java.util.UUID;
import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Point;
import android.graphics.Rect;
import android.graphics.Typeface;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.os.Environment;
import android.util.AttributeSet;
import android.view.Display;
import android.view.MotionEvent;
import android.widget.EditText;
import android.widget.ImageView;
public class DrawView2 extends ImageView {
private HashMap<String, ColorBall2> HashBall ;
private String balID = ""; // variable to know what ball is being dragged
public final String PTPPSERVICE_DERECTORY = "/PTPPservice/";
private Bitmap bitmap;
private EditText ed;
private Paint paint = new Paint();
private Paint paint2 = new Paint();
private Paint pTouch = new Paint();
private EditText addtext;
private Context ctx;
private String imagePath;
private boolean removeBall = false;
int viewWidth = 0;
int viewHeight = 0;
double bitmapHight =0;
double bitmapWidth =0;
double ratio =0;
double startX = 0;
double endX= 0;
double startY= 0;
double endY = 0;
public DrawView2(Context context, AttributeSet atts,String image1) {
super(context, atts);
this.ctx = context;
this.imagePath = image1;
setFocusable(true);
paint.setStyle(Paint.Style.FILL_AND_STROKE);
paint.setColor(Color.BLACK);
paint.setTypeface(Typeface.DEFAULT_BOLD);
paint2.setStyle(Paint.Style.FILL_AND_STROKE);
paint2.setColor(Color.RED);
addtext = (EditText) ((Activity) ctx).findViewById(R.id.edittextaddtext);
String filePath = Environment.getExternalStorageDirectory().toString() + imagePath;
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 4;
bitmap = BitmapFactory.decodeFile(filePath,options);
// SAVE RATIO
int x = bitmap.getWidth();
int y = bitmap.getHeight();
if(y>x)
ratio = ((double)y)/x;
if(x>y)
ratio = ((double)x)/y;
if(y==x)
ratio = 1;
Drawable bit = new BitmapDrawable(bitmap);
setImageDrawable(bit);
}
public double getRatio() {
return ratio;
}
public HashMap<String, ColorBall2> getHashBall() {
return HashBall;
}
// RETURN THE ON SCREEN RESIZED BITMAP
public double getOnScreenBitmapHight(){
return bitmapHight;
}
public double getOnScreenBitmapWidth(){
return bitmapWidth;
}
// BITMAP SIZE
public int getBitmapHight(){
return bitmap.getHeight();
}
public int getBitmapWidth(){
return bitmap.getWidth();
}
// GET IMAGEVIEW HIGHT WIDTH
public int getViewWidth() {
return viewWidth;
}
public int getViewHeight() {
return viewHeight;
}
// START END X Y
public double getStartX() {
return startX;
}
public double getEndX() {
return endX;
}
public double getStartY() {
return startY;
}
public double getEndY() {
return endY;
}
// SET BALL TEXT
public void addTextToBall(String text) {
if(balID != "")
HashBall.get(balID).setText(text);
}
// PATH
public String getImagePath() {
return imagePath;
}
// THE ORIGINAL INSAMPELSIZE=4 BITMAP
public Bitmap getBitmap() {
return bitmap;
}
// STOP DRAWAING THE BALL
public void removeBall(boolean value) {
removeBall = value;
}
// THE RECT THAT RETURN WRONG VALUE
public Rect getRect(){
Rect r = getDrawable().copyBounds();
int drawLeft = r.left;
int drawTop = r.top;
int drawRight = r.right;
int drawBottom = r.bottom;
return r;
}
@Override
protected void onSizeChanged(int xNew, int yNew, int xOld, int yOld){
super.onSizeChanged(xNew, yNew, xOld, yOld);
viewWidth = xNew;
viewHeight = yNew;
}
public void addBall(){
// HERE I TRY TO CALCULATE THE BOUNDS LEFT,RIGHT,TOP AND BOTTOM EDGE OF THE BITMAP
//NOT GOING THAT GOOD
if(HashBall == null)
HashBall = new HashMap<String,ColorBall2>();
//X
double drawAbleWidth = viewWidth/ratio;
startX = (viewWidth-drawAbleWidth)/2;
double drawAbleHight = viewHeight/ratio;
startY = drawAbleHight/2;
int ballY = (viewHeight/2);
int ballX = (viewWidth/2);
Point point1 = new Point();
point1.x = (int) ballX;
point1.y = (int) ballY;
String uuId = UUID.randomUUID().toString();
HashBall.put(uuId,(new ColorBall2(ctx,R.drawable.pen1, point1,uuId)));
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
//canvas.drawCircle(10,10,10,null);
if(!removeBall && HashBall != null){
for (String key : HashBall.keySet()) {
//System.out.println("Key: " + key + ", Value: " + map.get(key));
if(addtext!=null)
//canvas.drawCircle(HashBall.get(key).getX(), HashBall.get(key).getY(), 10, paint2);
canvas.drawBitmap(HashBall.get(key).getBitmap(), HashBall.get(key).getX()-10, HashBall.get(key).getY()-80, null);
canvas.drawText (HashBall.get(key).getText() + " X="+HashBall.get(key).getX() + " Y="+HashBall.get(key).getY()
, HashBall.get(key).getX(), HashBall.get(key).getY(), paint);
}
}
}
// events when touching the screen
@Override
public boolean onTouchEvent(MotionEvent event) {
int eventaction = event.getAction();
int X = (int)event.getX();
int Y = (int)event.getY();
switch (eventaction )
{
case MotionEvent.ACTION_DOWN: // touch down so check if the finger is on a ball
balID = "";
for (String key : HashBall.keySet()) {
// check if inside the bounds of the ball (circle)
// get the center for the ball
int centerX = HashBall.get(key).getX() + 15;
int centerY = HashBall.get(key).getY() + 15;
// calculate the radius from the touch to the center of the ball
double radCircle = Math.sqrt( (((centerX-X)*(centerX-X)) + (centerY-Y)*(centerY-Y)));
// if the radius is smaller then 23 (radius of a ball is 22), then it must be on the ball
if (radCircle < 33){
balID = HashBall.get(key).getID();
addtext.setText(HashBall.get(key).getText());
break;
}
}
break;
case MotionEvent.ACTION_MOVE: // touch drag with the ball
// move the balls the same as the finger
if (balID != "") {
HashBall.get(balID).setX(X-25);
HashBall.get(balID).setY(Y-25);
}
break;
case MotionEvent.ACTION_UP:
// touch drop - just do things here after dropping
break;
}
// redraw the canvas
invalidate();
return true;
}
}
Debería poder obtener las coordenadas (x, y) del dibujo dentro, si eso es lo que está buscando. Prueba esto:
ImageView img = (ImageView)findViewById(R.id.img);
Rect r = img.getDrawable().getBounds();
int drawLeft = r.left;
int drawTop = r.top;
int drawRight = r.right;
int drawBottom = r.bottom;
drawLeft
es tu valor de X.
drawTop
es tu valor Y.
Si conoce las proporciones, solo puede derivar el ancho del margen que se colocará al lado de la imagen.
// These holds the ratios for the ImageView and the bitmap
double bitmapRatio = ((double)bitmap.getWidth())/bitmap.getHeight()
double imageViewRatio = ((double)imageView.getWidth())/imageView.getHeight()
Ahora, si bitmapRatio es más grande que imageViewRatio, sabe que esto significa que el bitmap es más ancho que la vista de imagen si tienen la misma altura. En otras palabras, tendrá espacios en blanco en la parte superior e inferior.
Por el contrario, si bitmapRatio es más pequeño que imageViewRatio, entonces tendrá espacios en blanco a la izquierda y la derecha. ¡De esto puedes obtener una de las coordenadas bastante trivialmente ya que será 0!
if(bitmapRatio > imageViewRatio)
{
drawLeft = 0;
}
else
{
drawTop = 0;
}
Para obtener la otra coordenada, piense en el segundo caso donde tiene espacio a la izquierda y derecha. En este caso, las alturas del mapa de bits y el imageView son iguales y, por lo tanto, la relación entre los anchos es igual a la relación entre los índices. Puede usar esto para calcular el ancho del mapa de bits, ya que conoce el ancho de la imageView. De manera similar, puedes calcular las alturas si el ancho es igual, excepto que tienes que usar la inversa de la relación entre las relaciones, ya que la anchura es inversamente proporcional a la relación:
if(bitmapRatio > imageViewRatio)
{
drawLeft = 0;
drawHeight = (imageViewRatio/bitmapRatio) * imageView.getHeight();
}
else
{
drawTop = 0;
drawWidth = (bitmapRatio/imageViewRatio) * imageView.getWidth();
}
Una vez que tenga el ancho o alto del mapa de bits, obtener el espacio al lado es simple, es solo la mitad de la diferencia entre el mapa de bits y el ancho o alto de imageView:
if(bitmapRatio > imageViewRatio)
{
drawLeft = 0;
drawHeight = (imageViewRatio/bitmapRatio) * imageView.getHeight();
drawTop = (imageView.getHeight() - drawHeight)/2;
}
else
{
drawTop = 0;
drawWidth = (bitmapRatio/imageViewRatio) * imageView.getWidth();
drawLeft = (imageView.getWidth() - drawWidth)/2;
}
Tuve un montón de problemas con eso, resulta ser bastante simple :)
float points[] = {bitmap.getWidth()/2,bitmap.getHeight()/2}; matrix.mapPoints(points); matrix.postScale(scale, scale, points[0], points[1]);