如何镜像和调整具有固定宽度和高度的图像部分

IT技术 css image reactjs react-native
2021-04-27 14:23:58

在此处输入图片说明

我正在构建“从照片标记”功能。

  1. 当用户移动或捏住图像上的方块时,
  2. PanResponder 改变 x 坐标(左)、y 坐标(顶)、正方形长度(thumbSize)的状态
  3. 有了数据,我想实时显示方块的部分

所以下面这张图片应该放在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
/>

这是来自:How to show the only part of the image 的连续问题

它有效,但解决方案不符合我的期望。

  • 它不会改变宽度和高度(我想修复将图像从“正方形的宽度”调整为“70”的每个宽度和高度)
  • 它打破了整个风格(A,所有,所有的东西都消失了)

几天来我一直试图解决这个想法,但找不到确切的方法。


更新:我几乎解决了,但调整大小很重要

我换ImageCroppedImage(新组件)

<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)。

在此处输入图片说明

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>

好吧,我终于设法创建了一个有效的 React Native 代码(以前从未使用过它,抱歉,如果它是 noobish 代码),就像我的其他答案一样

这是代码:

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

这是小吃

我真的希望它有帮助!!祝你好运!!

编辑:好的,我会解释一下我在这里做什么。

首先,我设置了一个状态,其参数会根据某些事件而改变:

 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以将图像向左移动,因此 locationX 将位于标签的中心。

那只是为了定位。要缩放它,只需将图像的大小和 locationX 乘以相同的值。注意我在裁剪样式中将图像的宽度和高度与 SIZERATIO 相乘

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

这种缩放的例子:

如果您的图像宽度为 200,并且您想将其缩放到一半,则将其乘以 0.5。因此,如果您单击左侧开始的 180 像素,则缩放图像的等效像素也必须乘以 0.5,结果为 90。

如果有什么我没有解释得足够清楚,请再问我一次,我很乐意为您提供帮助。