redimensionar - tamaño imagen css background




Cómo duplicar y cambiar el tamaño de la parte de la imagen con ancho y altura fijos (2)

Estoy construyendo la funcionalidad "Etiquetar desde la foto".

  1. Cuando el usuario mueve o pellizca el cuadrado en la imagen,
  2. PanResponder cambia el estado de la coordenada x (izquierda), la coordenada y (arriba), la longitud del cuadrado (thumbSize)
  3. Con los datos, quiero mostrar la parte del cuadrado en tiempo real

Por lo tanto, esta imagen a continuación debe colocarse a la izquierda de A, Todo Todo de la imagen de arriba.

Aquí está la parte del render que muestra la imagen "recortada".

console.log(left) // 80
console.log(top) // 200
console.log(thumbSize) // 150
<Image
      source={{uri: image}}
      style={{height:70, width: 70, bottom: (-top), right: (-left)
      }} <- style is not complete. I'm putting some example code
/>

Este es un problema continuo de: Cómo mostrar la única parte de la imagen .

Funciona pero la solución no cumple mis expectativas.

  • No está cambiando el ancho y la altura (quiero arreglar el tamaño de la imagen desde 'el ancho del cuadrado' hasta '70' para cada ancho y alto)
  • Rompe todo el estilo (A, Todo, Todas las cosas desaparecen)

Estuve tratando de resolver esta idea por días pero no pude encontrar el camino exacto.

Actualización: casi lo resolví pero cambiar el tamaño importa

Cambié Image to CroppedImage (nuevo componente)

<CroppedImage
      source={{uri: image}}
      cropTop={top}
      cropLeft={left}
      cropWidth={thumbSize}
      cropHeight={thumbSize}
      width={width(100)}
      height={width(100)}
      resizeMode="contain" />

Aquí está CroppedImage

return (
  <View style={[{
    overflow: 'hidden',
    height: this.props.cropHeight,
    width: this.props.cropWidth,
    backgroundColor: 'transparent'
    }, this.props.style]}>
    <Image style={{
      position: 'absolute',
      top: this.props.cropTop * -1,
      left: this.props.cropLeft * -1,
      width: this.props.width,
      height: this.props.height
    }}
      source={this.props.source}
      resizeMode={this.props.resizeMode}>
      {this.props.children}
    </Image>
  </View>
);

Parece funcionar, pero no puede redimensionar (desde el ancho cuadrado x alto hasta 70x70).


Hice un violín para mostrar qué cálculos tienes que hacer para colocar y cambiar el tamaño de tu imagen de etiqueta correctamente:

$('#image').click(function(event) {
  var size_ratio = .6;

  var img_src = $(this).attr('src');
  
  var tag = $('#tag-rectangle');
  
  var top_position = tag.height()/2 - event.offsetX*size_ratio;
  var left_position = tag.width()/2 - event.offsetY*size_ratio;
  $('#tag-rectangle').css({
  	'background-image': 'url('+img_src+')',
    'background-position': top_position +'px '+ left_position + 'px',
    'background-size': $(this).width()*size_ratio + 'px ' + $(this).height()*size_ratio + 'px'
    });
});
#tag-rectangle {
  width: 50px;
  height: 50px;
  border: 1px solid black;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<img id="image" src="http://fakeimg.pl/250x100/" alt="">

<div id="tag-rectangle"></div>


Bueno, finalmente logré crear un código de React Native que funcione (nunca lo usé antes, lo siento si es un código no deseado) haciendo lo mismo que en mi otra respuesta .

Aquí está el código:

import React, { Component } from 'react';
import { TouchableWithoutFeedback, ImageBackground, Image, View, StyleSheet } from 'react-native';

const IMAGEURI = 'http://fakeimg.pl/300x300/';
const SIZERATIO = .6;
const IMAGEWIDTH = 300;
const IMAGEHEIGHT = 300;
const CROPIMAGEWIDTH = 100;
const CROPIMAGEHEIGHT = 100;

export default class App extends Component {
  state = {
    style: {
      marginLeft: 0,
      marginTop: 0,
    },
    uri: ''
  };

  repositionImage(event) {
    this.setState({
      style: {
        marginLeft: CROPIMAGEWIDTH/2 - event.nativeEvent.locationX*SIZERATIO,
        marginTop: CROPIMAGEHEIGHT/2 - event.nativeEvent.locationY*SIZERATIO
      },
      uri: IMAGEURI
    });
  }

  render() {
    return (
      <View>
        <TouchableWithoutFeedback onPress={(event) => this.repositionImage(event)}>
          <View>
            <Image
              style={styles.image}
              source={{ uri: IMAGEURI }}
            />
          </View>
        </TouchableWithoutFeedback>
        <View style={styles.tag}>
          <ImageBackground style={[styles.cropped,this.state.style]} source={{uri: this.state.uri }} />
        </View>
      </View>
    );
  }
}

const styles = StyleSheet.create({
  image: {
    width: IMAGEWIDTH,
    height: IMAGEHEIGHT,
  },

  tag: {
    borderWidth: 1,
    borderColor: '#000',
    width: CROPIMAGEWIDTH,
    height: CROPIMAGEHEIGHT,
    overflow: 'hidden'
  },

  cropped: {
    width: IMAGEWIDTH*SIZERATIO,
    height: IMAGEHEIGHT*SIZERATIO
  }
});

Y aquí está el Snack

¡Realmente espero que haya ayudado! ¡¡Buena suerte!!

EDIT: Ok, explicaré un poco lo que estoy haciendo aquí.

Primero, configuro un estado con los parámetros que cambiarán en función de algún evento:

 state = {
    style: {
      marginLeft: 0,
      marginTop: 0,
    },
    uri: ''
  };

Luego, hago que el componente obtenga sus propiedades de ese estado:

<ImageBackground style = {[styles.cropped, this.state.style ]} source = {{uri: this.state.uri }} />

Finalmente, preparo el evento onPress para llamar a una función que actualizará el estado:

<TouchablewithoutFeedback onPress = { (event) => this.repositionImage (event) }>

Aquí estoy alimentando mi función con el objeto del evento, así estaré disponible para obtener las coordenadas donde el usuario presionó.

Esa última función toma los datos del evento y actualiza el estado. La vista se actualizará automáticamente con los nuevos datos de estado.

repositionImage(event) {
  this.setState({
    style: {
      marginLeft: CROPIMAGEWIDTH/2 - event.nativeEvent.locationX*SIZERATIO,
      marginTop: CROPIMAGEHEIGHT/2 - event.nativeEvent.locationY*SIZERATIO
    },
    uri: IMAGEURI
  });
}

Para posicionar la imagen, simplemente hago una operación matemática:

CROPIMAGEWIDTH es el ancho de mi elemento de etiqueta, así que para obtener el centro lo divido por 2. Luego, restamos la ubicación X del evento para mover la imagen a la izquierda, por lo que la ubicación X estará en el centro de la etiqueta.

Eso es solo para posicionamiento. Para escalar, simplemente multiplique el tamaño de la imagen y la ubicaciónX por el mismo valor. Nota: multipliqué el ancho y el alto de la imagen con SIZERATIO en el estilo recortado

cropped: {
  width: IMAGEWIDTH*SIZERATIO,
  height: IMAGEHEIGHT*SIZERATIO
}

Un ejemplo de este escalado:

Si su imagen tiene 200 de ancho y desea escalarla a la mitad, multiplique por 0.5. Por lo tanto, si hace clic en, digamos, el píxel 180 empezando por la izquierda, el píxel equivalente para su imagen escalada tendrá que multiplicarse por 0.5 también y será 90.

Si hay algo que no le expliqué con la suficiente claridad, solo pregúntame de nuevo. Estaré encantado de ayudarte.





react-native