我有一个代码,负责裁剪图像并将其裁剪区域保存在div列表中。每个div代表每个裁剪的图像。但是问题是-我不希望它们这么大,我希望它们具有fixed
的高度和宽度,例如最多100x100px。
具有有效图像裁剪功能的Codesandbox: https://codesandbox.io/s/fast-frost-0b5tt 与裁剪逻辑相关的代码:
const width = pos.w + "px";
const height = pos.h + "px";
const marginLeft = - pos.x + "px";
const marginTop = - pos.y + "px";
return (
<div
key={i}
style={{
width: width,
height: height,
backgroundSize: "400px 300px",
backgroundPosition: `top ${marginTop} left ${marginLeft}`,
backgroundImage: "url('https://boygeniusreport.files.wordpress.com/2016/11/puppy-dog.jpg?quality=98&strip=all&w=400')"
}}
/>
);
您将看到图像裁剪效果很好,但是新创建的图像具有动态的高度和宽度。
问题:如何使这些新创建的div具有固定的宽度和高度,但又不破坏它?谢谢!
目标是使子级(裁剪的图像)的高度和宽度保持静态,但将背景图像保持在正确的位置。但是似乎我太笨拙,无法独自完成
答案 0 :(得分:3)
您的渲染函数中的以下更改将创建一个100px的正方形,其中心位于所选内容的中心点,或者尽可能接近以保持在图像范围内(我不确定如何从此处引用原始图像的宽度和高度)
...
const previews = crops.map(({ pos }, i) => {
const width = 100 + "px";
const height = 100 + "px";
let margx = (pos.w / 2) - 50 + pos.x;
let margy = (pos.h / 2) - 50 + pos.y;
if(margx < 0) margx = 0;
if(margy < 0) margy = 0;
// this needs origional image width & height (400,300) to get max values
const maxx = 400-100;
const maxy = 300-100;
if(margx > maxx) margx = maxx;
if(margy > maxy) margy = maxy;
const marginLeft = - margx + "px";
const marginTop = - margy + "px";
return (
<div
...
答案 1 :(得分:2)
如果同时固定高度和宽度,预览将看起来失真。所以我建议 仅固定高度。
const fixedHeight = 100;
const zoom = fixedHeight / pos.h;
const backgroundWidth = 400 * zoom;
const backgroundHeight = 300 * zoom;
const width = pos.w * zoom;
const height = fixedHeight;
const marginLeft = -pos.x * zoom;
const marginTop = -pos.y * zoom;
在此codesandbox demo中查看结果。
答案 2 :(得分:1)
我可以在@MunimMunna和@ArleighHix提出的解决方案之间提出一些建议,以改进这两种解决方案。 See result
// setup base image size
const imageBaseWidth = 400;
const imageBaseHeight = 300;
// choose thumbnail size and aspect ratio
const thumbHeight = 100;
const thumbWidth = 200;
// we check which axis needs to be filled to border
const zoomX = thumbWidth / pos.w;
const zoomY = thumbHeight / pos.h;
// you can improve it further by defining max zoom in level so that thumbnails don't show ugly pixels
// just use additional zoom = Math.min(zoom, maxZoom) and some more logic for handling min max margin offset so it wont go outside image bounds
const zoom = Math.max(zoomX, zoomY);
// scaling base image to best fit available space
const backgroundWidth = imageBaseWidth * zoom;
const backgroundHeight = imageBaseHeight * zoom;
// calculate offset to top left corner of biggest rect in selected region that keeps target aspect ratio
const marginLeft = thumbWidth / 2 - (pos.w / 2 + pos.x) * zoom;
const marginTop = thumbHeight / 2 - (pos.h / 2 + pos.y) * zoom;
return (
<div
className="preview"
key={i}
style={{
width: thumbWidth + "px",
height: thumbHeight + "px",
backgroundSize: `${backgroundWidth}px ${backgroundHeight}px`,
backgroundPosition: `top ${marginTop}px left ${marginLeft}px`,
backgroundImage: "url('https://boygeniusreport.files.wordpress.com/2016/11/puppy-dog.jpg?quality=98&strip=all&w=400')"
}}
/>
);
它在选择区域内选择最大的可能区域,以保持目标缩略图的纵横比,并在需要时对其进行放大。您可以使用fixedHeight
,fixedWidth
答案 3 :(得分:1)
我会尝试在没有jcrop库的情况下进行重写,以更好地访问所有道具,大小和位置等。 https://stackblitz.com/edit/react-7ubxaa