저자는 기술 다양성 기금(Diversity in Tech Fund)을 기부를 위한 글쓰기(Write for Donations) 프로그램의 일환으로 선정했습니다.
소개
디지털 이미지 처리는 컴퓨터를 사용하여 이미지를 분석하고 조작하는 방법입니다. 이 과정은 이미지를 읽고, 이미지를 변경하거나 향상시키는 방법을 적용한 다음 처리된 이미지를 저장하는 것을 포함합니다. 사용자가 업로드한 콘텐츠를 처리하는 애플리케이션에서 이미지 처리를 하는 것이 일반적입니다. 예를 들어, 사용자가 이미지를 업로드할 수 있는 웹 애플리케이션을 작성 중이라면, 사용자가 불필요하게 큰 이미지를 업로드할 수 있습니다. 이는 애플리케이션의 로드 속도에 부정적인 영향을 미칠 수 있으며, 또한 서버 공간을 낭비할 수 있습니다. 이미지 처리를 사용하면 애플리케이션이 모든 사용자 업로드 이미지의 크기를 조절하고 압축하여 애플리케이션 성능을 크게 향상시키고 서버 디스크 공간을 절약할 수 있습니다.
Node.js에는 sharp, jimp, gm 모듈 등의 이미지를 처리하는 데 사용할 수 있는 라이브러리 생태계가 있습니다. 이 문서에서는 sharp 모듈에 중점을 둡니다. sharp는 다양한 이미지 파일 형식을 지원하는 인기 있는 Node.js 이미지 처리 라이브러리입니다. 이 형식에는 JPEG, PNG, GIF, WebP, AVIF, SVG 및 TIFF가 포함됩니다.
이 튜토리얼에서는 sharp를 사용하여 이미지의 메타데이터를 읽고 크기를 조정하며 이미지 형식을 변경하고 이미지를 압축하는 방법을 알아볼 것입니다. 그런 다음 이미지를 잘라내고 회색조로 변환하고 회전시키고 이미지를 흐리게 할 것입니다. 마지막으로 이미지를 합성하고 이미지에 텍스트를 추가할 것입니다. 이 튜토리얼을 완료하면 Node.js에서 이미지를 처리하는 방법에 대한 좋은 이해를 갖게 될 것입니다.
필수 전제 조건
이 튜토리얼을 완료하려면 다음이 필요합니다:
-
로컬 개발 환경에서 Node.js 설정합니다. Node.js 및 npm을 시스템에 설치하는 방법은 Node.js 설치 및 로컬 개발 환경 만들기를 참고하세요.
-
Node.js 프로그램 작성 및 실행에 대한 기본 지식이 있어야 합니다. 기본 사항을 배우려면 Node.js에서 첫 프로그램 작성 및 실행하기를 참고하세요.
-
JavaScript에서 비동기 프로그래밍에 대한 기본적인 이해가 필요합니다. 비동기 프로그래밍을 검토하려면 JavaScript의 이벤트 루프, 콜백, 프로미스 및 Async/Await 이해하기를 참고하세요.
단계 1 — 프로젝트 디렉토리 설정 및 이미지 다운로드
코드 작성을 시작하기 전에 이 기사에서 사용할 코드와 이미지가 포함된 디렉토리를 만들어야합니다.
터미널을 열고 다음 명령을 사용하여 프로젝트를위한 디렉토리를 생성하십시오 : mkdir
새로 생성된 디렉토리로 이동하려면 다음 명령을 사용하십시오 : cd
npm init
명령을 사용하여 package.json
파일을 만들어 프로젝트 종속성을 추적합니다:
-y
옵션은 npm
이 기본 package.json
파일을 만들도록 지시합니다.
다음으로, 종속성으로 sharp
를 설치하십시오 :
이 자습서에서 다음 세 개의 이미지를 사용합니다:
다음으로 curl
명령을 사용하여 프로젝트 디렉터리에 이미지를 다운로드합니다.
첫 번째 이미지를 다운로드하는 다음 명령을 사용하십시오. 이 명령은 이미지를 sammy.png
로 다운로드합니다:
다음으로 다음 명령을 사용하여 두 번째 이미지를 다운로드하십시오. 이 명령은 이미지를 underwater.png
로 다운로드합니다:
마지막으로 다음 명령을 사용하여 세 번째 이미지를 다운로드하십시오. 이 명령은 이미지를 sammy-transparent.png
로 다운로드합니다:
프로젝트 디렉터리와 종속성이 설정되었으므로 이제 이미지 처리를 시작할 준비가 되었습니다.
단계 2 — 이미지 읽기 및 메타데이터 출력
이 섹션에서는 이미지를 읽고 해당 메타데이터를 추출하는 코드를 작성합니다. 이미지 메타데이터는 이미지에 내장된 텍스트로, 이미지의 유형, 너비 및 높이와 같은 이미지에 대한 정보를 포함합니다.
메타데이터를 추출하려면 먼저 sharp 모듈을 가져와야 합니다. 그런 다음, 이미지 경로를 인수로 전달하여 sharp의 인스턴스를 생성합니다. 그 후에는 인스턴스에 metadata() 메소드를 연결하여 메타데이터를 추출하고 콘솔에 기록합니다.
이를 위해 원하는 텍스트 편집기에서 readImage.js 파일을 생성하고 엽니다. 이 튜토리얼에서는 터미널 텍스트 편집기로 nano를 사용합니다.:
다음으로 파일 맨 위에 sharp를 require합니다:
sharp는 promise 기반의 이미지 처리 모듈입니다. sharp 인스턴스를 생성하면 프로미스가 반환됩니다. 이 프로미스를 then 메소드를 사용하여 해결할 수 있습니다. 또는 보다 깔끔한 구문을 가진 async/await를 사용할 수 있습니다.
async/await 구문을 사용하려면 함수의 시작 부분에 async 키워드를 배치하여 비동기 함수를 생성해야 합니다. 이렇게 하면 이미지를 읽을 때 반환된 프로미스를 해결하기 위해 함수 내부에서 await 키워드를 사용할 수 있습니다.
readImage.js 파일에 비동기 함수인 getMetadata()를 정의하여 이미지를 읽고 메타데이터를 추출한 다음 콘솔에 기록합니다:
getMetadata()
는 function
라벨 앞에 정의된 async
키워드를 통해 비동기 함수입니다. 이를 통해 함수 내에서 await
구문을 사용할 수 있습니다. getMetadata()
함수는 이미지를 읽고 해당 이미지의 메타데이터가 포함된 객체를 반환합니다.
함수 본문에서는 이미지를 읽기 위해 sharp()
를 호출하여 이미지 경로를 인수로 사용합니다. 여기에서는 sammy.png
을 사용합니다.
이미지 경로 외에도, sharp()
는 JPEG, PNG, GIF, WebP, AVIF, SVG 또는 TIFF 형식의 이미지 데이터를 Buffer, Uint8Array, 또는 Uint8ClampedArray에서도 읽을 수 있습니다.
이제 이미지를 읽기 위해 sharp()
를 사용하면 sharp
인스턴스가 생성됩니다. 그런 다음 이 인스턴스에 sharp 모듈의 metadata()
메서드를 연결합니다. 이 메서드는 이미지 메타데이터가 포함된 객체를 반환하며, 이를 metadata
변수에 저장하고 console.log()
를 사용하여 내용을 기록합니다.
이제 프로그램은 이미지를 읽고 해당 메타데이터를 반환할 수 있습니다. 그러나 프로그램이 실행 중에 오류가 발생하면 프로그램이 충돌합니다. 이를 해결하기 위해 발생하는 오류를 캡처해야 합니다.
그렇게 하려면 try...catch
블록 내부에 있는 getMetadata()
함수 내의 코드를 감싸세요:
이제 try
블록 내에서 이미지를 읽고 메타데이터를 추출하여 로깅합니다. 이 과정 중에 오류가 발생하면 실행이 catch
섹션으로 건너뛰어 오류를 로그에 기록하여 프로그램이 충돌하지 않도록 합니다.
마지막으로, 강조 표시된 줄을 추가하여 getMetadata()
함수를 호출하세요:
이제 파일을 저장하고 종료하세요. 파일에 대한 변경 내용을 저장하려면 y
를 입력하고 파일 이름을 확인하기 위해 ENTER
키나 RETURN
키를 누르세요.
Output{
format: 'png',
width: 750,
height: 483,
space: 'srgb',
channels: 3,
depth: 'uchar',
density: 72,
isProgressive: false,
hasProfile: false,
hasAlpha: false
}
단계 3 — 이미지 크기 조정, 이미지 형식 변경 및 압축
크기 조정은 이미지의 차원을 수정하여 이미지 파일 크기에 영향을 미치지 않고 이미지를 조정하는 프로세스입니다. 이 섹션에서는 이미지 크기를 조정하고 이미지 유형을 변경하며 이미지를 압축합니다. 이미지 압축은 이미지 파일 크기를 줄이는 과정으로 품질을 손상시키지 않습니다.
먼저, sharp
인스턴스에서 resize()
메서드를 연결하여 이미지 크기를 조정하고 프로젝트 디렉토리에 저장합니다. 둘째로, 조정된 이미지에 format()
메서드를 연결하여 형식을 png
에서 jpeg
로 변경합니다. 추가로 이미지를 압축하고 디렉토리에 저장하기 위해 format()
메서드에 옵션을 전달합니다.
텍스트 편집기에서 resizeImage.js
파일을 생성하고 엽니다:
다음 코드를 추가하여 이미지를 150px
너비와 97px
높이로 조정합니다:
resizeImage()
함수는 sharp 모듈의 resize()
메서드를 sharp
인스턴스에 연결합니다. 이 메서드는 객체를 인수로 취합니다. 객체에서는 width
와 height
속성을 사용하여 원하는 이미지 차원을 설정합니다. width
를 150
으로, height
를 97
로 설정하면 이미지가 150px
너비로, 97px
높이로 만들어집니다.
이미지를 조정한 후에는 sharp 모듈의 toFile()
메서드를 연결합니다. 이 메서드는 이미지 경로를 인수로 취합니다. 인수로 sammy-resized.png
를 전달하면 작업 디렉토리에 해당 이름으로 이미지 파일을 저장합니다.
이제 파일을 저장하고 종료합니다. 터미널에서 프로그램을 실행합니다:
출력은 없지만 프로젝트 디렉토리에 sammy-resized.png
이름으로 새 이미지 파일이 생성된 것을 확인할 수 있어야 합니다.
로컬 머신에서 이미지를 열어주세요. 이미지의 폭은 150px
이고 높이는 97px
입니다:
이미지를 크기 조정할 수 있으므로, 다음으로는 크기가 조정된 이미지 형식을 png
에서 jpeg
로 변환하고 이미지를 압축하여 작업 디렉토리에 저장합니다. 이를 위해 resize()
메서드 뒤에 연결할 toFormat()
메서드를 사용할 것입니다.
강조된 코드를 추가하여 이미지 형식을 jpeg
으로 변경하고 압축합니다:
resizeImage()
함수 내에서 sharp 모듈의 toFormat()
메서드를 사용하여 이미지 형식을 변경하고 압축합니다. toFormat()
메서드의 첫 번째 인수는 이미지를 변환할 이미지 형식을 포함하는 문자열입니다. 두 번째 인수는 이미지를 향상시키고 압축하는 출력 옵션을 포함하는 선택적 객체입니다.
이미지를 압축하려면, mozjpeg
속성을 전달합니다. 이 속성은 품질을 희생하지 않고 이미지를 압축하기 위한 boolean 값이 들어 있습니다. mozjpeg 기본값을 사용하여 이미지를 압축합니다. 객체는 더 많은 옵션을 사용할 수 있습니다. 자세한 내용은 sharp 문서를 참조하세요.
참고: toFormat()
메서드의 두 번째 인수에는 각 이미지 형식에 따라 다른 속성을 가진 객체가 필요합니다. 예를 들어, mozjpeg
속성은 JPEG
이미지에서만 허용됩니다.
그러나 다른 이미지 형식에도 quality
, compression
, lossless
와 같은 동등한 옵션이 있습니다. 이미 압축하려는 이미지 형식에서 허용되는 옵션 유형을 확인하려면 문서를 참조하십시오.
다음으로, 압축된 이미지를 다른 파일 이름으로 저장하도록 toFile()
메서드에 다른 파일 이름을 전달하십시오. sammy-resized-compressed.jpeg
로.
이제 파일을 저장하고 종료한 다음 다음 명령으로 코드를 실행하십시오.
출력은 없지만 이미지 파일 sammy-resized-compressed.jpeg
이 프로젝트 디렉토리에 저장됩니다.
로컬 머신에서 이미지를 열면 다음 이미지가 표시됩니다:
이제 이미지를 압축했으므로 압축이 성공적인지 확인하기 위해 파일 크기를 확인하십시오. 터미널에서 sammy.png
의 파일 크기를 확인하려면 du
명령을 실행하십시오:
-h
옵션은 킬로바이트, 메가바이트 등으로 파일 크기를 보여주는 인간이 읽기 쉬운 출력을 생성합니다.
명령을 실행한 후 다음과 같은 출력이 표시됩니다:
Output120K sammy.png
원본 이미지의 크기가 120 킬로바이트임을 보여줍니다.
다음으로 sammy-resized.png
의 파일 크기를 확인하십시오:
명령을 실행한 후 다음 출력이 표시됩니다:
Output8.0K sammy-resized.png
sammy-resized.png
의 크기가 120 킬로바이트에서 8 킬로바이트로 줄었습니다. 이는 크기 조정 작업이 파일 크기에 영향을 미친다는 것을 보여줍니다.
이제 sammy-resized-compressed.jpeg
의 파일 크기를 확인하십시오:
명령을 실행한 후 다음 출력이 표시됩니다:
Output4.0K sammy-resized-compressed.jpeg
sammy-resized-compressed.jpeg
의 크기가 이제 8 킬로바이트에서 4 킬로바이트로 줄어들었으며, 4 킬로바이트를 절약하여 압축이 작동되었음을 보여줍니다.
이제 이미지 크기를 조정하고 형식을 변경하고 압축한 후 이미지를 자르고 그레이스케일로 변환하겠습니다.
단계 4 — 이미지 자르기 및 그레이스케일로 변환
이 단계에서는 이미지를 자르고 그레이스케일로 변환합니다. 자르기는 이미지에서 원치 않는 영역을 제거하는 프로세스입니다. extend()
메소드를 사용하여 sammy.png
이미지를 자릅니다. 그 후 자른 이미지 인스턴스에 grayscale()
메소드를 연결하여 그레이스케일로 변환합니다.
텍스트 편집기에서 cropImage.js
를 만들고 엽니다:
cropImage.js
파일에 다음 코드를 추가합니다:
cropImage()
함수는 이미지를 읽고 잘린 이미지를 반환하는 비동기 함수입니다. try
블록 내에서 sharp
인스턴스가 이미지를 읽습니다. 그런 다음 인스턴스에 연결된 sharp 모듈의 extract()
메서드는 다음 속성을 가진 객체를 사용합니다:
width
: 잘라내려는 영역의 너비입니다.height
: 잘라내려는 영역의 높이입니다.top
: 잘라내려는 영역의 수직 위치입니다.left
: 잘라내려는 영역의 수평 위치입니다.
width
를 500
으로 설정하고 height
를 330
으로 설정하면, sharp가 자르려는 이미지 위에 투명 상자를 만듭니다. 상자에 들어갈 수 있는 이미지 부분은 유지되고 나머지는 잘립니다:
top
과 left
속성은 상자의 위치를 제어합니다. left
를 120
으로 설정하면 상자가 이미지의 왼쪽 가장자리에서 120px 떨어진 위치에 배치되며, top
을 70
으로 설정하면 상자가 이미지의 위쪽 가장자리에서 70px 떨어진 위치에 배치됩니다.
상자 안에 들어간 이미지 영역은 sammy-cropped.png
로 따로 추출되어 저장됩니다.
파일을 저장하고 나가십시오. 터미널에서 프로그램을 실행하십시오:
출력은 표시되지 않지만 이미지 sammy-cropped.png
이 프로젝트 디렉토리에 저장됩니다.
로컬 머신에서 이미지를 엽니다. 이미지가 잘린 것을 볼 수 있어야 합니다:
이미지를 자르고 나면 이미지를 그레이스케일로 변환할 것입니다. 이를 위해 sharp
인스턴스에 grayscale
메서드를 연결할 것입니다. 다음과 같이 강조된 코드를 추가하여 이미지를 그레이스케일로 변환하십시오:
cropImage()
함수는 잘린 이미지를 그레이스케일로 변환하기 위해 sharp
모듈의 grayscale()
메서드를 sharp
인스턴스에 연결합니다. 그런 다음 프로젝트 디렉터리에 이미지를 sammy-cropped-grayscale.png
으로 저장합니다.
파일을 저장하고 종료하려면 CTRL+X
를 누르십시오.
터미널에서 코드를 실행하십시오:
로컬 머신에서 sammy-cropped-grayscale.png
을 엽니다. 이제 이미지가 그레이스케일로 표시됩니다:
이미지를 자르고 추출했으므로 회전 및 흐림 효과를 사용하여 작업할 것입니다.
단계 5 — 이미지 회전 및 흐리게 만들기
이 단계에서는 sammy.png
이미지를 33
도 각도로 회전합니다. 그리고 회전된 이미지에 가우시안 블러를 적용할 것입니다. 가우시안 블러는 가우시안 함수를 사용하여 이미지를 흐리게 만드는 기술로, 이미지의 잡음 수준과 세부 정보를 줄입니다.
텍스트 편집기에서 rotateImage.js
파일을 만드세요.
rotateImage.js
파일에 다음 코드 블록을 작성하여 sammy.png
이미지를 33
도로 회전하는 함수를 만듭니다:
rotateImage()
함수는 이미지를 읽고 33
도로 회전한 이미지를 반환하는 비동기 함수입니다. 함수 내에서 sharp 모듈의 rotate()
메서드는 두 개의 인수를 사용합니다. 첫 번째 인수는 33
도의 회전 각도입니다. 기본적으로 sharp는 회전된 이미지의 배경을 검정색으로 만듭니다. 검정 배경을 제거하려면 두 번째 인수로 개체를 전달하여 배경을 투명하게 만듭니다.
개체에는 background
속성이 있으며 이는 RGBA 색상 모델을 정의하는 개체를 보유합니다. RGBA는 빨강, 녹색, 파랑 및 알파의 약자입니다.
-
r
: 빨간 색상의 강도를 제어합니다.0
에서255
까지의 정수 값을 허용합니다.0
은 색상이 사용되지 않음을 의미하고,255
는 가장 높은 강도의 빨강입니다. -
g
: 녹색 색상의 강도를 제어합니다.0-255
사이의 정수 값을 허용합니다.0
은 녹색이 사용되지 않음을 의미하고,255
는 가장 높은 강도의 녹색입니다. -
b
:파랑
의 강도를 제어합니다.0
에서255
까지의 정수 값을 허용합니다.0
은 파란색이 사용되지 않음을 의미하고,255
는 가장 높은 강도의 파랑입니다. -
alpha
:r
,g
, 및b
속성으로 정의된 색의 불투명도를 제어합니다.0
또는0.0
은 색을 투명하게 만들고1
또는1.1
은 색을 불투명하게 만듭니다.
alpha
속성을 사용하려면 반드시 r
, g
, 및 b
의 값을 정의하고 설정해야 합니다. r
, g
, 및 b
값을 0
으로 설정하면 검은색이 생성됩니다. 투명한 배경을 생성하려면 먼저 색을 정의한 다음 alpha
를 0
으로 설정하면 됩니다.
이제 파일을 저장하고 종료합니다. 터미널에서 스크립트를 실행합니다:
프로젝트 디렉토리에서 sammy-rotated.png
의 존재 여부를 확인합니다. 로컬 머신에서 엽니다.
이미지가 33
도 각도로 회전된 것을 볼 수 있어야 합니다:
다음으로, 회전된 이미지를 흐리게 만듭니다. 그것은 sharp
인스턴스에 blur()
메서드를 연결하여 달성할 것입니다.
이미지를 흐리게 하려면 아래 강조된 코드를 입력하십시오:
rotateImage()
함수는 이미지를 읽어들이고, 회전시키며, 이미지에 가우시안 블러를 적용합니다. 이는 sharp 모듈의 blur()
메서드를 사용하여 이미지에 가우시안 블러를 적용합니다. 이 메서드는 0.3
과 1000
사이의 시그마 값을 포함하는 단일 인수를 허용합니다. 예를 들어 4
를 전달하면 시그마 값이 4
인 가우시안 블러가 적용됩니다. 이미지가 흐릿해진 후, 흐림이 적용된 이미지를 저장할 경로를 정의합니다.
이제 스크립트는 회전된 이미지를 시그마 값이 4
인 가우시안 블러로 흐리게 할 것입니다. 파일을 저장하고 나가면 터미널에서 스크립트를 실행하십시오:
스크립트를 실행한 후에 로컬 머신에서 sammy-rotated-blurred.png
파일을 엽니다. 이제 회전된 이미지가 흐릿하게 표시됩니다:
이제 이미지를 회전하고 흐리게 한 후에, 이미지를 다른 이미지 위에 겹쳐서 조합하겠습니다.
단계 6 — composite()
를 사용하여 이미지 조합하기
이미지 조합은 두 개 이상의 별개의 사진을 결합하여 단일 이미지를 만드는 과정입니다. 이는 다른 사진에서 최상의 요소를 빌려와 효과를 만들기 위해 수행됩니다. 또 다른 일반적인 사용 사례는 로고로 이미지에 워터마크를 삽입하는 것입니다.
이 섹션에서는 sammy-transparent.png
을 underwater.png
위에 합성할 것입니다. 이를 통해 sammy가 깊은 바다를 헤엄치는 것처럼 보이게 될 것입니다. 이미지를 합성하려면 sharp
인스턴스에 composite()
메서드를 연결해야합니다.
텍스트 편집기에서 compositeImage.js
파일을 만들고 엽니다:
이제 다음 코드를 compositeImages.js
파일에 추가하여 두 이미지를 합성하는 함수를 만듭니다:
compositeImages()
함수는 먼저 underwater.png
이미지를 읽습니다. 그런 다음 sharp 모듈의 composite()
메서드를 연결합니다. 이 메서드는 인수로 배열을 취합니다. 배열은 sammy-transparent.png
이미지를 읽는 단일 객체를 포함합니다. 객체에는 다음과 같은 속성이 있습니다:
input
: 처리된 이미지 위에 합성하려는 이미지의 경로를 취합니다. 또한 Buffer, Uint8Array, 또는 Uint8ClampedArray를 입력으로 사용할 수 있습니다.top
: 합성하려는 이미지의 수직 위치를 제어합니다.top
을50
으로 설정하면sammy-transparent.png
이미지가underwater.png
이미지의 상단에서 50px 만큼 이동합니다.left
: 이미지를 다른 이미지 위에 합성할 때의 수평 위치를 제어합니다.left
를50
으로 설정하면sammy-transparent.png
이미지를underwater.png
이미지의 왼쪽 가장자리에서 50px만큼 이동시킵니다.
composite()
메서드는 처리된 이미지와 동일한 크기 또는 작은 이미지가 필요합니다.
composite()
메서드가 무엇을 하는지 시각화하려면, 이미지 스택을 만드는 것처럼 생각하십시오. sammy-transparent.png
이미지가 underwater.png
이미지 위에 배치됩니다.
top
및 left
값은 sammy-transparent.png
이미지의 underwater.png
이미지에 대한 상대적인 위치를 지정합니다.
스크립트를 저장하고 파일을 종료합니다. 이미지 합성을 생성하려면 스크립트를 실행합니다.
node compositeImages.js
로컬 기계에서 sammy-underwater.png
을 엽니다. 이제 sammy-transparent.png
이 underwater.png
이미지 위에 합성된 것을 볼 수 있습니다.
composite()
메서드를 사용하여 이미지를 합성했습니다. 다음 단계에서는 composite()
메서드를 사용하여 이미지에 텍스트를 추가합니다.
단계 7 — 이미지에 텍스트 추가
이 단계에서는 이미지에 텍스트를 작성합니다. 작성 시점에서 샤프는 이미지에 텍스트를 추가하는 기본 방법이 없습니다. 텍스트를 추가하려면 먼저 확장 가능한 벡터 그래픽 (SVG)를 사용하여 텍스트를 그리는 코드를 작성합니다. SVG 이미지를 생성한 후 sammy.png
이미지와 composite
메서드를 사용하여 이미지를 결합하는 코드를 작성합니다.
SVG는 웹을 위한 벡터 그래픽을 생성하기 위한 기반 마크업 언어입니다. 텍스트나 원, 삼각형과 같은 모양을 그리거나 복잡한 모양 인 일러스트, 로고 등을 그릴 수 있습니다. 복잡한 모양은 Inkscape와 같은 그래픽 도구로 생성되며 SVG 코드를 생성합니다. SVG 모양은 품질을 잃지 않고 어떤 크기로든 렌더링 및 확장할 수 있습니다.
텍스트 편집기에서 addTextOnImage.js
파일을 만들고 엽니다.
addTextOnImage.js
파일에 다음 코드를 추가하여 SVG 컨테이너를 생성합니다:
addTextOnImage()
함수는 네 개의 변수 width
, height
, text
, 그리고 svgImage
를 정의합니다. width
는 정수 750
을, height
는 정수 483
을 보유합니다. text
는 문자열 Sammy the Shark
을 보유합니다. 이것은 SVG를 사용하여 그릴 텍스트입니다.
svgImage
변수에는 svg
요소가 들어 있습니다. svg
요소에는 width
와 height
두 개의 속성이 있으며, 이는 이전에 정의한 width
와 height
변수를 보간합니다. svg
요소는 주어진 너비와 높이에 따라 투명한 컨테이너를 생성합니다.
svg
요소에 width
를 750
, height
를 483
으로 지정하여 SVG 이미지가 sammy.png
와 동일한 크기가 되도록 했습니다. 이는 텍스트가 sammy.png
이미지의 중앙에 위치하도록 도와줍니다.
다음으로 텍스트 그래픽을 그릴 것입니다. SVG 컨테이너에 Sammy the Shark
를 그리는 하이라이트된 코드를 추가하십시오:
SVG text
요소에는 네 가지 속성이 있습니다: x
, y
, text-anchor
, 그리고 class
. x
와 y
는 SVG 컨테이너에 그리는 텍스트의 위치를 정의합니다. x
속성은 텍스트를 가로로 위치시키고, y
속성은 텍스트를 세로로 위치시킵니다.
x
를 50%
로 설정하면 x-축을 기준으로 컨테이너의 중앙에 텍스트가 그려지고, y
를 50%
로 설정하면 SVG 이미지의 y-축 중앙에 텍스트가 위치합니다.
text-anchor
는 텍스트를 수평으로 정렬합니다. text-anchor
를 middle
로 설정하면 지정한 x
좌표에서 텍스트를 중앙 정렬합니다.
class
는 text
요소에 클래스 이름을 정의합니다. 이 클래스 이름을 사용하여 text
요소에 CSS 스타일을 적용할 것입니다.
${text}
는 text
변수에 저장된 문자열 Sammy the Shark
을 보간합니다. 이것이 SVG 이미지에 그려질 텍스트입니다.
다음으로, CSS를 사용하여 텍스트를 스타일링하는 강조 표시된 코드를 추가하세요:
이 코드에서 fill
은 텍스트 색상을 검정으로 변경하고, font-size
는 글꼴 크기를 변경하며, font-weight
는 글꼴 두께를 변경합니다.
이 시점에서 SVG로 Sammy the Shark
텍스트를 그리기 위해 필요한 코드를 작성했습니다. 다음으로, SVG 이미지를 png
로 저장하여 SVG가 텍스트를 그리는 방법을 확인할 것입니다. 그 후에는 SVG 이미지를 sammy.png
과 병합할 것입니다.
SVG 이미지를 png
로 저장하는 강조 표시된 코드를 추가하세요:
Buffer.from()
는 SVG 이미지로부터 Buffer 객체를 생성합니다. 버퍼는 이진 데이터를 저장하는 임시 메모리 공간입니다.
버퍼 객체를 생성한 후에는 버퍼 객체를 입력으로 사용하여 sharp
인스턴스를 만듭니다. 이미지 경로 외에도 sharp는 버퍼, Uint9Array 또는 Uint8ClampedArray도 허용합니다.
마지막으로 프로젝트 디렉토리에 SVG 이미지를 svg-image.png
로 저장합니다.
전체 코드는 다음과 같습니다:
파일을 저장하고 나가면 다음 명령을 사용하여 스크립트를 실행합니다:
node addTextOnImage.js
참고: 만약 옵션 2 — NodeSource PPA를 사용하여 Apt로 Node.js 설치 또는 옵션 3 — Node 버전 관리자를 사용하여 Node 설치 방법을 사용하여 Node.js를 설치하고 fontconfig error: cannot load default config file: no such file: (null)
오류가 발생한다면, 폰트 구성 파일을 생성하기 위해 fontconfig
을 설치하세요.
서버의 패키지 인덱스를 업데이트한 후 apt install
을 사용하여 fontconfig
을 설치하세요.
로컬 머신에서 svg-image.png
을 엽니다. 이제 투명 배경으로 렌더링된 Sammy the Shark
텍스트가 표시됩니다:
SVG 코드가 텍스트를 그리는 것을 확인했으므로 텍스트 그래픽을 sammy.png
에 합성합니다.
다음 강조된 코드를 sammy.png
이미지 위에 SVG 텍스트 그래픽 이미지를 합성하려면 다음 코드를 추가합니다.
composite()
메서드는 SVG 이미지를 svgBuffer
변수에서 읽고, 이를 sammy.png
의 상단에서 0
픽셀, 좌측 가장자리에서 0
픽셀 위치로 설정합니다. 그런 다음, 합성된 이미지를 sammy-text-overlay.png
로 저장합니다.
파일을 저장하고 닫은 후 다음 명령을 사용하여 프로그램을 실행합니다:
로컬 머신에서 sammy-text-overlay.png
을 엽니다. 이미지 위에 텍스트가 추가된 것을 볼 수 있어야 합니다:
이제 composite()
메서드를 사용하여 SVG로 생성된 텍스트를 다른 이미지에 추가했습니다.
결론
이 기사에서는 Node.js에서 이미지를 처리하는 데에 날카로운 방법을 사용하는 방법을 배웠습니다. 먼저 이미지를 읽기 위한 인스턴스를 생성하고 metadata()
메서드를 사용하여 이미지 메타데이터를 추출했습니다. 그런 다음 resize()
메서드를 사용하여 이미지 크기를 조정했습니다. 이후에는 format()
메서드를 사용하여 이미지 유형을 변경하고 이미지를 압축했습니다. 다음으로 이미지를 잘라내고 회색조로 만들고 회전시키고 흐림 효과를 줄 수 있는 다양한 sharp 메서드를 사용했습니다. 마지막으로 composite()
메서드를 사용하여 이미지를 합성하고 이미지에 텍스트를 추가했습니다.
추가 sharp 메서드에 대한 자세한 내용은 sharp 문서를 참조하세요. Node.js를 계속 학습하고 싶다면 Node.js 코딩 방법 시리즈를 확인하세요.
Source:
https://www.digitalocean.com/community/tutorials/how-to-process-images-in-node-js-with-sharp