2011-05-16 12 views
16

Si tengo un ImageView que llena la pantalla.
El fondo de ImageView se establece en color verde.
Coloco un mapa de bits en ImageView, manteniendo las proporciones del mapa de bits.android: cómo obtener la posición x/y del borde de la imagen dentro de la vista de imagen

Una foto vertical en este diseño se mostrará verde en el lado 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 extremo verde y el mapa de bits comienzan?

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 ..

Dado que escalo la imagen en SampleSize = 4; y el ImageView lo reduce aún más, guardar esta nueva imagen le dará una imagen pequeña y pequeña de aproximadamente 250x350.

Lo que quiero es utilizar los x/posiciones y y transferir el texto escrito a la imagen original inSampleSize = 4 o a la imagen sdcard 1500x3000

sé y leer otras preguntas sobre este que tengo que " Haz los cálculos matemáticos "yo mismo Solo necesito esta pequeña respuesta.

Olvidé que puedo tomar una captura de pantalla para aclarar.

esto es lo que se vea como: (me da una nueva pluma al presionar el botón de "pluma" cada pluma mantenga su propio texto y posición única en la pantalla

enter image description here

Aquí está el imageview

.
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; 
     } 
    } 

Respuesta

23

Si conoce las relaciones, puede derivar el ancho del margen que se colocará al costado 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 el bitmapRatio es mayor que el imageViewRatio, usted sabe que esto significa que el mapa de bits es más ancha que la imageview si tienen la misma altura. En otras palabras, tendrá espacios en blanco en la parte superior & inferior.

Por el contrario, si bitmapRatio es más pequeño que imageViewRatio, tendrá espacios en blanco a la izquierda y a la derecha. ¡De esto puedes obtener una de las coordenadas de forma muy trivial ya que será 0!

if(bitmapRatio > imageViewRatio) 
{ 
    drawLeft = 0; 
} 
else 
{ 
    drawTop = 0; 
} 

para obtener la otra coordenada, pensar en el segundo caso en el que usted tiene el espacio dejado & derecha. Aquí las alturas del mapa de bits y de la vista de imagen son iguales y, por lo tanto, la relación entre los anchos es igual a la relación entre las relaciones.Puedes usar esto para calcular el ancho del mapa de bits, ya que conoces el ancho del imageView. Del mismo modo se puede averiguar las alturas si la anchura son iguales, excepto que usted tiene que utilizar la inversa de la relación entre las proporciones que la anchura es inversamente proporcional al 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 la anchura o altura del mapa de bits, consiguiendo el espacio al lado es simple, es sólo la mitad de la diferencia entre la anchura o la altura de mapa de bits y 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; 
} 
+0

gracias voy a trabajar con esto. Espero que tengas la recompensa 50+. No puedo ver la recompensa, tal vez caduque, por favor, ¡consejo! – Erik

+1

Creo que la recompensa expiró, pero no te preocupes – pheelicks

+3

Estoy buscando lo mismo, pero ¿por qué es la única solución TAN malditamente complicada? ImageView debe saber dónde coloca la imagen, entonces, ¿por qué tengo que "recalcular" exactamente lo mismo? ¿Dónde está el captador de ImageView para determinar el offset y el tamaño? En realidad, estar enojado con la API de Android ahora ... :( – Zordid

3

usted debe ser capaz de obtener las coordenadas (x, y) las coordenadas de la estirable dentro, si eso es lo que estás 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 su valor de X.

drawTop es su valor Y.

+0

Sí eso es lo que estaba pensando, androide tiene .getBounds() agradable gracias lo probaré y volveré a aceptar la respuesta – Erik

+0

del código que obtengo drawBottom = 648 pero la imagen en la imagen es solo 374, @Override onSizeChanged devuelve 374. drawLeft = 0, drawTop = 0. En el costo anterior x = 31. eso es lo que quiero – Erik

+0

drawBottom debe ser la posición Y absoluta de la imagen en la pantalla, por lo que podría ser correcto. No estoy seguro de por qué drawLeft muestra cero. Depende cuando lo llames, sin embargo. No estoy seguro si el dibujante se midió en 'onSizeChanged()'. – kcoppock

1

Tenía un LOTTT de problemas con que a mí mismo, resulta ser en realidad bastante simple :)

float points[] = {bitmap.getWidth()/2,bitmap.getHeight()/2}; matrix.mapPoints(points); matrix.postScale(scale, scale, points[0], points[1]);

+0

Muy mala respuesta de donde obtienes la escala? – Renetik

23

Aquí es un método que quería compartir, devolverá el desplazamiento del mapa de bits dentro de un 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; 
    } 
+1

Esta es una manera fácil y efectiva Me pregunto por qué esto no pudo llamar la atención. +1 por mi parte. – Pawan

+2

Gracias, ya olvidé esta solución;) –

Cuestiones relacionadas