Подтвердить что ты не робот

Как зеркалировать и изменять размер части изображения с фиксированной шириной и высотой

введите описание изображения здесь

Я создаю функциональность "Tagging from photo".

  • Когда пользователь перемещает или зажимает квадрат на изображении,
  • PanResponder изменяет состояние x-координаты (слева), y-координаты (сверху), длины квадрата (thumbSize)
  • С данными я хочу показать часть квадрата в реальном времени

Итак, это изображение ниже должно быть помещено слева от A, Все Все от изображения выше.

введите описание изображения здесь

Вот часть рендера, показывающая "обрезанное" изображение.

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

Это непрерывная проблема: Как показать единственную часть изображения.

Это работает, но решение не соответствует моим ожиданиям.

  • Он не меняет ширину и высоту (я хочу исправить изменение размера изображения с "ширины квадрата" до "70" для каждой ширины и высоты).
  • Он разбивает весь стиль (A, All, все исчезает)

Я пытался решить эту идею в течение нескольких дней, но не смог найти точный способ.


Обновление: Я почти решил его, но изменил размер

Я изменил Image на CroppedImage (новый компонент)

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

Вот 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>
);

Кажется, работает , но не может изменять размер (от квадратной ширины x до 70x70).

введите описание изображения здесь

4b9b3361

Ответ 1

Ну, наконец, мне удалось создать рабочий код React Native (никогда не использовал его раньше, извините, если это noobish code), делая то же самое, что и в моем другом ответе..

Вот код:

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

И вот Snack

Я действительно надеюсь, что это помогло! Удачи!

EDIT: Хорошо, я немного объясню, что я здесь делаю.

Сначала я установил State с параметрами, которые будут меняться в зависимости от какого-либо события:

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

Затем я заставляю компонент получать его свойства из этого состояния:

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

Наконец, я создаю событие onPress для вызова функции, которая обновит состояние:

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

Здесь я загружаю свою функцию с событием, поэтому я буду доступен для получения координат, где пользователь нажал.

Эта последняя функция принимает данные из события и обновляет состояние. Представление автоматически обновится с новыми данными состояния.

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

Чтобы поместить изображение, я просто выполняю математическую операцию:

CROPIMAGEWIDTH - это ширина элемента моего тега, поэтому для того, чтобы получить центр, я делю его на 2. Затем я вычитаю locationX события, чтобы переместить изображение в слева, так что местоположение X будет находиться в центре тега.

Это только для позиционирования. Для масштабирования просто умножьте размер изображения и местоположениеX на одно значение. Примечание. Я увеличил ширину и высоту изображения с помощью SIZERATIO в стиле обрезанный

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

Пример такого масштабирования:

Если ваше изображение имеет ширину 200 и вы хотите масштабировать его до половины, вы умножаете его на 0,5. Поэтому, если вы нажмете на пиксель 180, начинающийся слева, эквивалентный пиксель для масштабированного изображения также должен быть умножен на 0,5, и он будет равен 90.

Если что-то я не объяснял достаточно ясно, просто спросите меня снова, я буду рад помочь вам.

Ответ 2

Я сделал скрипку, чтобы показать, какие вычисления вы должны сделать, чтобы правильно позиционировать и изменить размер изображения тега:

$('#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>