1.0.18 • Published 10 months ago

@cp949/web-image-util v1.0.18

Weekly downloads
-
License
MIT
Repository
github
Last release
10 months ago

web-image-util

web-image-util은 웹이미지 유틸리티 라이브러리입니다.

설치

web-image-util은 npm에 등록되어 있습니다.

npm install @cp949/web-image-util

사용법

이미지 유틸리티와 리사이즈를 제공합니다.

다음과 같이 import 할 수 있습니다.

import { Images } from "@cp949/web-image-util";

Resize

대략 다음과 같이 사용할 수 있습니다

const img = await Images.resizeFrom(imgSrc)
  .centerCrop({ size: 300 }) // or centerInside, fit, fill
  .toElement("jpeg"); // or 'png', return HTMLImageElement

Resize 이미지 소스

Images.resizeFrom( imageSrc )에서 imageSrc 부분에 다음과 같은 항목을 지정할 수 있습니다.

  • HTMLImageElement
  • Blob
  • HTTP URL string(ex: http://...)
  • Data URL string(ex: data://...)
  • SVG XML string(ex: <svg ...>...</svg>)

Resize 결과물 타입

이미지를 리사이징한 결과물은 다음과 유형을 지원합니다.

  • HTMLImageElement
  • Data url
  • Blob
  • File
const element = await Images.resizeFrom(imgSrc)
  .centerCrop({ size: 300 })
  .toElement("png"); // HTMLImageElement

const dataUrl = await Images.resizeFrom(imgSrc)
  .centerCrop({ size: 300 })
  .toDataUrl("png"); // Data url string

const blob = await Images.resizeFrom(imgSrc)
  .centerCrop({ size: 300 })
  .toBlob("png"); // Blob

const file = await Images.resizeFrom(imgSrc)
  .centerCrop({ size: 300 })
  .toFile("png", "output.png"); // File
  • 파일 확장자는 자동으로 교정됩니다. 아래는 output.svg를 지정했지만, output.png로 고쳐집니다.
const file = await Images.resizeFrom(imgSrc)
  .centerCrop({ size: 300 })
  .toFile("png", "output.svg"); // autofix to output.png

Resize 이미지 스케일

  • 간단하게 사용할 수 있는 scale이 있습니다.
    • scale
  • 그 외에 네가지의 스케일 타입이 존재합니다.
    • centerCrop
    • centerInside
    • fit
    • fill

Resize - scale

  • 이미지를 확대/축소 합니다.
await Images.resizeFrom(img)
  .scale(2) // 2배 확대
  .toElement("png");
await Images.resizeFrom(img)
  .scale({ scaleX: 2, scaleY: 1 }) // x축으로 2배 확대
  .toElement("png");

Resize - centerCrop

  • 이미지를 주어진 사각형에 가득 채웁니다.
  • 가득 채울때 이미지의 일부는 잘릴 수 있습니다.
  • 지정한 사각형보다 큰 이미지의 경우, 축소됩니다.
  • 지정한 사각형보다 작은 이미지의 경우, 확대됩니다.
await Images.resizeFrom(img)
  .centerCrop({
    size: {
      width: 400,
      height: 300,
    },
  })
  .toElement("png");

Resize Options

전체 옵션은 다음과 같습니다. 다른 스케일 타입에서도 같은 의미입니다.

centerCrop({
  size: { width: 400, height: 300 }, // or size : 400,
  crossOrigin: "Anonymous",
  quality: 0.5, // canvas.toDataURL()에서 사용합니다
  backgroundColor: "#fff", // default: 'transparent'
  padding: 8, // or {top:8, bottom:8, left:8, right:8 }
});

scale

배율을 지정하여 이미지를 확대/축소할 수도 있습니다. size 대신 scale을 지정합니다. scale을 지정하면 결과 이미지의 크기는 원본 이미지 크기에 scale 곱한 값이 됩니다.

centerCrop({
  scale: 1.5, // or scale : {scaleX: 1.5, scaleY: 1.5}
  crossOrigin: "Anonymous",
  quality: 0.5,
  backgroundColor: "#fff",
  padding: 8,
});

sizescale의 우선 순위

  • size와 scale을 둘 다 지정한 경우 scale은 무시됩니다. 즉, 지정한 사각형 영역이 우선순위를 갖습니다.
  • size와 scale을 둘 다 지정하지 않은 경우는 scale이 1인 것과 동일하게 동작합니다. 즉, 크기가 변경되지 않습니다. 이미지의 포맷만 변경되겠네요.

Resize - 결과 이미지의 크기

padding에 의해 결과 이미지의 크기가 조금 달라집니다.

이미지의 원본 크기가 800x800인 경우를 예로 듭니다.

  • size 기준 결과 이미지 크기
    • size를 지정한 경우 최종 결과 이미지는 무조건 size입니다.
    • 아래의 결과 이미지의 크기는 400x400입니다.
    • 패딩을 제거한, 순수 이미지 영역의 크기는 380x380입니다.
Images.resizeFrom(img)
  .centerCrop({
    size: 400,
    padding: 10,
  })
  .toDataUrl("png");
  • scale 기준 결과 이미지 크기
    • scale을 지정한 경우 이미지가 scale 된 후에, padding 만큼 이미지가 늘어납니다.
    • 아래의 결과 이미지의 크기는 420x420입니다.
    • 패딩을 제거한 순수 이미지 영역의 크기는 400x400입니다.
Images.resizeFrom(img)
  .centerCrop({
    scale: 0.5,
    padding: 10,
  })
  .toDataUrl("png");

Resize - centerInside

  • 이미지를 주어진 사각형안에 배치합니다.
  • 이미지의 일부가 잘리지 않습니다.
  • 지정한 사각형 보다 큰 이미지의 경우 축소됩니다.
  • 확대하지는 않습니다. 지정한 사각형 보다 작은 이미지의 경우, 사각형의 중앙에 배치하며, 확대하지는 않습니다. 확대하지 않는 것이 다음에 설명할 fit과의 차이점입니다.
// imgSrc: 800x800일때 output: 400x300
await Images.resizeFrom(imgSrc)
  .centerInside({
    size: {
      width: 400,
      height: 300,
    },
  })
  .toElement("png");

centerInside는 보통 큰 이미지를 잘림 없이 사각형 영역에 넣을 때 사용합니다.

  • trim 옵션
    • 예를 들어 800x800 이미지를 400x300 사각형에 넣으면, 결과 이미지의 크기는 400x300이고, 거기서 이미지 영역의 크기는 300x300이 됩니다. 만약 결과 이미지의 크기를 이미지 영역의 크기로 만들고 싶다면 trim 옵션을 사용할 수 있습니다.
    • trim 은 centerInside에만 존재하는 옵션입니다.
// imgSrc: 800x800일때 output: 300x300
await Images.resizeFrom(imgSrc)
  .centerInside({
    size: {
      width: 400,
      height: 300,
    },
    trim: true,
  })
  .toElement("png");
fit
  • 이미지를 주어진 사각형안에 배치합니다.
  • 이미지의 일부가 잘리지 않습니다.
  • 지정한 사각형 보다 큰 이미지의 경우 축소됩니다.
  • 여기까지는 centerInside와 동일합니다. fit은 지정한 사각형 보다 작은 이미지의 경우, 사각형 크기만큼 확대됩니다. centerInside는 확대하지 않습니다.
await Images.resizeFrom(img)
  .fit({
    size: {
      width: 400,
      height: 300,
    },
  })
  .toElement("png");
fill
  • 이미지를 주어진 사각형안에 가득 채웁니다.
  • 이미지는 잘리지 않습니다.
  • 이미지의 Aspect ratio는 사각형의 비율로 변형됩니다.
  • 지정한 사각형 보다 큰 이미지의 경우 축소됩니다.
  • 지정한 사각형 보다 작은 이미지의 경우, 사각형 크기만큼 확대됩니다.
await Images.resizeFrom(img)
  .fit({
    size: {
      width: 400,
      height: 300,
    },
  })
  .toElement("png");

SimpleResizer

  • 기본 4가지 유형의 리사이징 fit, centerInside, fit, fill이 간단하긴 하지만, 실제로는 한가지 일만 하는 Resizer가 편리합니다.
  • SimpleResizer는 한가지 일만 하는 함수들을 제공합니다.
Images.simpleResizer.atMostWidth(source, 300);
Images.simpleResizer.atMostHeight(source, 400);
Images.simpleResizer.atMostRect(source, { width: 300, height: 400 });
Images.simpleResizer.forceWidth(source, 300);
Images.simpleResizer.forceHeight(source, 300);
  • 실제로 사용할 때는 다름과 같이 사용할 수 있습니다.
const resizer = await Images.simpleResizer.atMostWidth(source, 300);
const dataUrl = await resizer.toDataUrl("png");

// 추가 변수 선언 없이 다음과 같이 할 수 있습니다.
const dataUrl = await Images.simpleResizer
  .atMostWidth(source, 300)
  .then((resizer) => resizer.toDataUrl("png"));

기타 이미지 유틸리티

  • 이미지 소스 다운로드
import { Images } from "@cp949/web-image-util";

Images.download(imageSrc, "test.png");

// imagsSrc:
//     HTMLImageElement
//     Blob
//     HTTP URL string(ex: http://...)
//     Data URL string(ex: data://...)
//     SVG XML string(ex: `<svg ...>...</svg>`)
  • 이미지 소스를 HTMLImageElement로 변환
import { Images } from "@cp949/web-image-util";

const img = await Images.toElement(imageSrc, "test.png");

// imagsSrc:
//     HTMLImageElement
//     Blob
//     HTTP URL string(ex: http://...)
//     Data URL string(ex: data://...)
//     SVG XML string(ex: `<svg ...>...</svg>`)
  • 기타 이미지 유틸리티
import { Images } from "@cp949/web-image-util";

// Images.util.base64ToBuffer (...)
// Images.util.blobToDataUrl (...)
// Images.util.blobToFile (...)
// Images.util.downloadBlob (...)
// Images.util.downloadLink (...)
// Images.util.fixBlobFileExt (...)
// Images.util.isSvgDataUrl (...)
// Images.util.svgToDataUrl (...)
// Images.util.urlToBlob (...)
// Images.util.urlToFile (...)
// Images.util.urlToBuffer (...)
// Images.util.urlToDataUrl (...)
// Images.util.urlToElement (...)

const blob = await Images.util.urlToBlob(url);
const file = await Images.util.urlToFile(url, "test.png");
const buffer: Uint8Array = await Images.util.urlToBuffer(url, "test.png");
const dataUrl = await Images.util.urlToDataUrl(url);
const img = await.Image.util.urlToElement(url);

const buf: Uint8Array = await Images.util.base64ToBuffer(base64str);
const dataUrl = await Images.util.blobToDataUrl(blob);
const file = await Images.util.blobToFile(blob, "test.png");

// return fixed file name by blob.type
const fixedFileName = Images.util.fixBlobFileExt(blob, "test.png");

const isSvg = Images.util.isSvgDataUrl("data:image/svg+xml...");

const dataUrl = Images.util.svgToDataUrl("<svg ...>...");

TODO

  • resize에 canvasHookFn 추가
const element = await Images.resizeFrom(imgSrc)
  .centerCrop({
    size: 300,
    canvasHookFn: (step, canvas, ctx) => {
      if (step === "preSetup") {
        ctx.imageSmoothingEnabled = true;
      } else if (step === "preDraw") {
        ctx.drawImage(bg, 0, 0);
      } else if (step === "postDraw") {
        ctx.drawImage(overlay, 0, 0);
      }
    },
  })
  .toElement("png"); // HTMLImageElement
1.0.18

10 months ago

1.0.16

10 months ago

1.0.11

3 years ago

1.0.10

3 years ago

1.0.9

3 years ago

1.0.8

3 years ago

1.0.7

3 years ago

1.0.5

3 years ago

1.0.4

3 years ago

1.0.3

3 years ago

1.0.2

3 years ago