如何在宽度和高度未知的Next.js中使用图像组件

tktrz96b  于 2022-10-21  发布在  其他
关注(0)|答案(8)|浏览(186)

从版本10开始,Next.js附带了内置的Image组件,该组件提供了图像优化和响应调整图像大小的功能。我非常喜欢它,我一直在我的网站上使用它来处理固定大小的图片。根据官方文件,除非是layout=fill,否则宽度和高度都是必需的道具。
现在,我想使用Image组件,即使我事先不知道宽度和高度。我有来自CMS的博客资源,其中图像的确切大小未知。在这种情况下,我可以使用Image组件吗?
任何帮助都将不胜感激。

nsc4cvqm

nsc4cvqm1#

是的,您可以将其与您提到的layout=fill选项一起使用。
在这种情况下,你需要为你的图片设置一个“纵横比”

<div style={{ position: "relative", width: "100%", paddingBottom: "20%" }} >
  <Image
    alt="Image Alt"
    src="/image.jpg"
    layout="fill"
    objectFit="contain" // Scale your image down to fit into the container
  />
</div>

你也可以使用objectFit="cover",它会放大你的图像,填满所有的容器。
这种方法的缺点是,它将被附加到您指定的width,它可以是相对的,比如“100%”,也可以是绝对的,比如“10rem”,但没有办法根据图像的大小自动设置宽度和高度,或者至少现在还没有。

qv7cva1a

qv7cva1a2#

👋
我也有同样的问题:我想使用Next/Image中的ImageMUI中的砖石ImageList中...
无论如何,这是我用来获得图像大小以及处理容器大小的诀窍:

import React, { FC, useState } from 'react';
    import styled from 'styled-components';
    import Image from 'next/image';

    interface Props {
      src: string;
    }
    export const MasonryItem: FC<Props> = ({ src }) => {
      const [paddingTop, setPaddingTop] = useState('0');

      return (
        <Container style={{ paddingTop }}>
          <Image
            src={src}
            layout="fill"
            objectFit="contain"
            onLoad={({ target }) => {
              const { naturalWidth, naturalHeight } = target as HTMLImageElement;
              setPaddingTop(`calc(100% / (${naturalWidth} / ${naturalHeight})`);
            }}
          />
        </Container>
      );
    };

    const Container = styled.div`
      position: relative;
    `;

**想法:**在加载时获取图像的大小,计算比例,并用它来使容器用填充顶部填充所需的空间。这样,无论您的图像大小如何,容器都将适合它。
备注,我没有在容器上使用宽度或高度,因为我的项目不需要它,但可能您的项目需要同时设置两者之一。

由于我还在开始使用Reaction&NextJS&TypeScrip,也许解决方案可以更漂亮,如果有人有改进的想法,我很乐意阅读它!🙏

vsmadaxz

vsmadaxz3#

如果你想保持原始图像的比例,你可以这样做:

<div
  style={{
    width: 150,
    height: 75,
    position: "relative",
  }}>
<Image
  src={"/images/logos/" + merger.companyLogoUrl}
  alt={merger.company}
  layout="fill"
  objectFit="contain"
/>

图像将填充到容器允许的最大尺寸。例如,如果您知道图像的宽度大于图像的长度,则只需设置容器的宽度,然后将容器高度设置为大于预测的图像高度即可。
因此,例如,如果您正在处理宽图像,您可以将容器宽度设置为150px,那么只要容器高度大于图像高度,图像就会以原始比例的高度显示。

aamkag61

aamkag614#

我写了一篇博客文章,详细介绍了如何在使用SSG的同时获取远程图像的大小。How to use Image component in Next.js with unknown width and height

import Image from "next/image";
import probe from "probe-image-size";

export const getStaticProps = async () => {
  const images = [
    { url: "https://i.imgur.com/uCxsmmg.png" },
    { url: "https://i.imgur.com/r4IgKkX.jpeg" },
    { url: "https://i.imgur.com/dAyge0Y.jpeg" }
  ];

  const imagesWithSizes = await Promise.all(
    images.map(async (image) => {
      const imageWithSize = image;
      imageWithSize.size = await probe(image.url);

      return imageWithSize;
    })
  );

  return {
    props: {
      images: imagesWithSizes
    }
  };
};
//...
export default function IndexPage({ images }) {
  return (
    <>
      {images?.map((image) => (
        <Image
          key={image.url}
          src={image.url}
          width={image.size.width}
          height={image.size.height}
        />
      ))}
    </>
  );
}
66bbxpm5

66bbxpm55#

上面的变种对我没有什么帮助,但我尝试了另一种方法来解决问题,它对我有效:

const [imageSize, setSmageSize] = useState({
  width: 1,
  height: 1
 });

<Image
  src={imgPath}
  layout="responsive"
  objectFit="contain"
  alt={alt}
  priority={true}
  onLoadingComplete={target => {
    setSmageSize({
      width: target.naturalWidth,
      height: target.naturalHeight
    });
   }}
  width={imageSize.width}
  height={imageSize.height}
/>
llew8vvj

llew8vvj6#

有时,您希望有不同的图像大小,如小、中、大。我们将道具传递给组件,并基于该道具使用不同的样式。在本例中,layout="fill"很方便。
填充时,如果元素是相对的,则图像会将宽度和高度拉伸到父元素的尺寸

const Card = (props) => {
  const { imgUrl, size } = props;
  const classMap = {
    large: styles.lgItem,
    medium: styles.mdItem,
    small: styles.smItem,
  };
  return (
      <div className={classMap[size]}>
        <Image src={imgUrl} alt="image" layout="fill" />
      </div>
  );
};

您为每种情况编写了CSS样式。重要的是你应该有足够的钱。例如:

.smItem {
  position: relative;
  width: 300px;
  min-width: 300px;
  height: 170px;
  min-height: 170px;
}

.mdItem {
  position: relative;
  width: 158px;
  min-width: 158px;
  height: 280px;
  min-height: 280px;
}

.lgItem {
  position: relative;
  width: 218px;
  min-width: 218px;
  height: 434px;
  min-height: 434px;
}
4nkexdtk

4nkexdtk7#

在大多数情况下,您希望在保持纵横比并设置自定义宽度属性的同时使用图像。这是我找到的一个解决方案。您必须在下一个项目中使用静态导入的图像。在下面的代码中,我使用tawindcss进行样式设置。

import React from 'react';
import Image from 'next/image';

import mintHeroImg from '../public/images/mint-hero.png';

export default function Lic() {
  return (
    <div className="w-[100px] relative">
      <Image src={mintHeroImg} alt="mint-hero" />
    </div>
  );
}

这将渲染一个宽度为100px、高度由图像比例决定的图像。相对位置是最基本的属性。希望我的解决方案能帮助你。谢谢。

xuo3flqw

xuo3flqw8#

<Image src={thumbnail || ""}
       alt="post-thumbnail"
       layout="responsive"
       objectFit="cover"
       width={6}
       height={4}
/>

宽度={6}高度={4}为比率
例如:正方形=>宽度={1}高度={1}

相关问题