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

hel*_*eer 13 css image reactjs react-native

在此输入图像描述

我正在构建"从照片标记"功能.

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

因此,下面的图像应放在A,All All的左侧,如上图所示.

在此输入图像描述

这是呈现"裁剪"图像的渲染部分.

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
/>
Run Code Online (Sandbox Code Playgroud)

这是一个持续存在的问题:如何显示图像的唯一部分.

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

  • 它没有改变宽度和高度(我想修复图像从每个宽度和高度的'宽度'到'70'调整大小)
  • 它打破了整个风格(A,All,All things disappear)

我一直试图解决这个问题好几天但找不到确切的方法.


更新:我几乎解决了它,但重新调整问题

我换ImageCroppedImage(新组件)

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

这是 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>
);
Run Code Online (Sandbox Code Playgroud)

它似乎工作但它无法调整大小(从方形宽度x高度到70x70).

在此输入图像描述

Fco*_*odr 7

我做了一个小提琴来展示你需要做些什么计算来正确定位和调整标签图像的大小:

$('#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'
    });
});
Run Code Online (Sandbox Code Playgroud)
#tag-rectangle {
  width: 50px;
  height: 50px;
  border: 1px solid black;
}
Run Code Online (Sandbox Code Playgroud)
<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>
Run Code Online (Sandbox Code Playgroud)


Fco*_*odr 5

好吧,我终于成功创建了一个有效的 React Native 代码(以前从未使用过它,如果它是菜鸟代码,抱歉),与我的其他答案中的操作相同。

这是代码:

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
  }
});
Run Code Online (Sandbox Code Playgroud)

这是小吃

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

编辑:好的,我会解释一下我在这里所做的事情。

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

 state = {
    style: {
      marginLeft: 0,
      marginTop: 0,
    },
    uri: ''
  };
Run Code Online (Sandbox Code Playgroud)

然后,我让组件从该状态获取其属性:

< 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
  });
}
Run Code Online (Sandbox Code Playgroud)

为了定位图像,我只需进行数学运算:

CROPIMAGEWIDTH是我的标签元素的宽度,因此为了获得中心,我将其除以 2。然后,我减去事件的locationX以将图像向左移动,以便 locationX 将位于标签的中心。

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

cropped: {
  width: IMAGEWIDTH*SIZERATIO,
  height: IMAGEHEIGHT*SIZERATIO
}
Run Code Online (Sandbox Code Playgroud)

这种缩放的例子:

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

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