シャープでNode.jsの画像を処理する方法
著者は、 Diversity in Tech Fund を選択して、 Write forDOnationsプログラムの一環として寄付を受け取りました。
序章
デジタル画像処理は、コンピュータを使用して画像を分析および操作する方法です。 このプロセスには、画像の読み取り、画像を変更または強調する方法の適用、および処理された画像の保存が含まれます。 ユーザーがアップロードしたコンテンツを処理するアプリケーションが画像を処理するのは一般的です。 たとえば、ユーザーが画像をアップロードできるWebアプリケーションを作成している場合、ユーザーは不要な大きな画像をアップロードする可能性があります。 これは、アプリケーションの読み込み速度に悪影響を及ぼし、サーバースペースを浪費する可能性があります。 画像処理を使用すると、アプリケーションはユーザーがアップロードしたすべての画像のサイズを変更して圧縮できます。これにより、アプリケーションのパフォーマンスが大幅に向上し、サーバーのディスク領域を節約できます。
Node.jsには、 Sharp 、 jimp 、 gmmoduleなどの画像の処理に使用できるライブラリのエコシステムがあります。 この記事では、シャープモジュールに焦点を当てます。 Sharpは人気のあるNode.js画像処理ライブラリで、 JPEG 、 PNG 、 GIF 、[ X154X] WebP 、 AVIF 、 SVG 、TIFF。
このチュートリアルでは、シャープを使用して画像を読み取り、そのメタデータを抽出し、サイズを変更し、画像形式を変更し、画像を圧縮します。 次に、画像のトリミング、グレースケール、回転、ぼかしを行います。 最後に、画像を合成し、画像にテキストを追加します。 このチュートリアルを終了すると、Node.jsで画像を処理する方法を十分に理解できるようになります。
前提条件
このチュートリアルを完了するには、次のものが必要です。
- Node.jsはローカル開発環境でセットアップされます。 Node.jsをインストールしてローカル開発環境を作成する方法に従って、システムにNode.jsとnpmをインストールする方法を学ぶことができます。
- Node.jsプログラムの作成方法と実行方法に関する基本的な知識。 Node.js で最初のプログラムを作成して実行する方法に従って、基本を学ぶことができます。
- JavaScriptでの非同期プログラミングの基本的な理解。 JavaScript でのイベントループ、コールバック、プロミス、非同期/待機について理解し、非同期プログラミングを確認してください。
ステップ1—プロジェクトディレクトリの設定と画像のダウンロード
コードの記述を開始する前に、この記事で使用するコードと画像を含むディレクトリを作成する必要があります。
ターミナルを開き、mkdirコマンドを使用してプロジェクトのディレクトリを作成します。
mkdir process_images
cdコマンドを使用して、新しく作成されたディレクトリに移動します。
cd process_images
npm initコマンドを使用してpackage.jsonファイルを作成し、プロジェクトの依存関係を追跡します。
npm init -y
-yオプションは、npmにデフォルトのpackage.jsonファイルを作成するように指示します。
次に、依存関係としてsharpをインストールします。
npm install sharp
このチュートリアルでは、次の3つの画像を使用します。
次に、curlコマンドを使用して、プロジェクトディレクトリ内のイメージをダウンロードします。
次のコマンドを使用して、最初のイメージをダウンロードします。 これにより、画像がsammy.pngとしてダウンロードされます。
curl -O https://assets.digitalocean.com/how-to-process-images-in-node-js-with-sharp/sammy.png
次に、次のコマンドを使用して2番目のイメージをダウンロードします。 これにより、画像がunderwater.pngとしてダウンロードされます。
curl -O https://assets.digitalocean.com/how-to-process-images-in-node-js-with-sharp/underwater.png
最後に、次のコマンドを使用して3番目のイメージをダウンロードします。 これにより、画像がsammy-transparent.pngとしてダウンロードされます。
curl -O https://assets.digitalocean.com/how-to-process-images-in-node-js-with-sharp/sammy-transparent.png
プロジェクトディレクトリと依存関係を設定すると、画像の処理を開始する準備が整います。
ステップ2—画像の読み取りとメタデータの出力
このセクションでは、画像を読み取り、そのメタデータを抽出するコードを記述します。 画像メタデータは、画像に埋め込まれたテキストであり、画像の種類、幅、高さなどの情報が含まれています。
メタデータを抽出するには、最初にシャープモジュールをインポートし、sharpのインスタンスを作成して、引数として画像パスを渡します。 その後、metadata()メソッドをインスタンスにチェーンして、メタデータを抽出し、コンソールにログインします。
これを行うには、お好みのテキストエディタでreadImage.jsファイルを作成して開きます。 このチュートリアルでは、nanoというターミナルテキストエディタを使用します。
nano readImage.js
次に、ファイルの先頭にあるsharpでrequireします。
process_images / readImage.js
const sharp = require("sharp");
シャープはプロミスベースの画像処理モジュールです。 sharpインスタンスを作成すると、promiseが返されます。 thenメソッドを使用してpromiseを解決するか、よりクリーンな構文を持つ async /awaitを使用できます。
async/await構文を使用するには、関数の先頭にasyncキーワードを配置して、非同期関数を作成する必要があります。 これにより、関数内でawaitキーワードを使用して、画像を読み取ったときに返されるpromiseを解決できます。
readImage.jsファイルで、非同期関数getMetadata()を定義して、イメージを読み取り、そのメタデータを抽出して、コンソールにログインします。
process_images / readImage.js
const sharp = require("sharp");
async function getMetadata() {
const metadata = await sharp("sammy.png").metadata();
console.log(metadata);
}
getMetadata()は、functionラベルの前に定義したasyncキーワードが指定された非同期関数です。 これにより、関数内でawait構文を使用できます。 getMetadata()関数は画像を読み取り、そのメタデータを含むオブジェクトを返します。
関数本体内で、sharp()を呼び出して画像を読み取ります。これは、引数として画像パスを取ります。ここでは、sammy.pngを使用します。
sharp()は、画像パスを取得する以外に、 Buffer 、 Uint8Array 、または Uint8ClampedArray に保存されている画像データを読み取ることもできます(画像がJPEGの場合)。 、PNG、GIF、WebP、AVIF、SVGまたはTIFF。
これで、sharp()を使用して画像を読み取ると、sharpインスタンスが作成されます。 次に、sharpモジュールのmetadata()メソッドをインスタンスにチェーンします。 このメソッドは、画像メタデータを含むオブジェクトを返します。このオブジェクトは、metadata変数に格納され、console.log()を使用してその内容をログに記録します。
これで、プログラムは画像を読み取り、そのメタデータを返すことができます。 ただし、実行中にプログラムがエラーをスローすると、クラッシュします。 これを回避するには、エラーが発生したときにエラーをキャプチャする必要があります。
これを行うには、 try ...catchブロック内のgetMetadata()関数内のコードをラップします。
process_images / readImage.js
const sharp = require("sharp");
async function getMetadata() {
try {
const metadata = await sharp("sammy.png").metadata();
console.log(metadata);
} catch (error) {
console.log(`An error occurred during processing: ${error}`);
}
}
tryブロック内で、画像を読み取り、そのメタデータを抽出してログに記録します。 この処理中にエラーが発生した場合、実行はcatchセクションにスキップし、プログラムのクラッシュを防ぐエラーをログに記録します。
最後に、強調表示された行を追加して、getMetadata()関数を呼び出します。
process_images / readImage.js
const sharp = require("sharp");
async function getMetadata() {
try {
const metadata = await sharp("sammy.png").metadata();
console.log(metadata);
} catch (error) {
console.log(`An error occurred during processing: ${error}`);
}
}
getMetadata();
次に、ファイルを保存して終了します。 yと入力してファイルに加えた変更を保存し、ENTERまたはRETURNキーを押してファイル名を確認します。
nodeコマンドを使用してファイルを実行します。
node readImage.js
次のような出力が表示されます。
Output{
format: 'png',
width: 750,
height: 483,
space: 'srgb',
channels: 3,
depth: 'uchar',
density: 72,
isProgressive: false,
hasProfile: false,
hasAlpha: false
}
画像を読み取ってメタデータを抽出したので、画像のサイズを変更し、形式を変更して、圧縮します。
ステップ3—サイズ変更、画像フォーマットの変更、および画像の圧縮
サイズ変更とは、画像から何も切り取らずに画像のサイズを変更するプロセスであり、画像ファイルのサイズに影響します。 このセクションでは、画像のサイズを変更し、画像の種類を変更し、画像を圧縮します。 画像圧縮は、品質を損なうことなく画像ファイルのサイズを縮小するプロセスです。
まず、resize()メソッドをsharpインスタンスからチェーンして画像のサイズを変更し、プロジェクトディレクトリに保存します。 次に、format()メソッドをサイズ変更された画像にチェーンして、フォーマットをpngからjpegに変更します。 さらに、format()メソッドにオプションを渡して、画像を圧縮してディレクトリに保存します。
テキストエディタでresizeImage.jsファイルを作成して開きます。
nano resizeImage.js
次のコードを追加して、画像のサイズを150pxの幅と97pxの高さに変更します。
process_images / resizeImage.js
const sharp = require("sharp");
async function resizeImage() {
try {
await sharp("sammy.png")
.resize({
width: 150,
height: 97
})
.toFile("sammy-resized.png");
} catch (error) {
console.log(error);
}
}
resizeImage();
resizeImage()関数は、シャープモジュールのresize()メソッドをsharpインスタンスにチェーンします。 このメソッドは、オブジェクトを引数として取ります。 オブジェクトでは、widthおよびheightプロパティを使用して、必要な画像のサイズを設定します。 widthを150に、heightを97に設定すると、画像の幅が150px、高さが97pxになります。 。
画像のサイズを変更した後、シャープモジュールのtoFile()メソッドをチェーンします。このメソッドは、画像パスを引数として取ります。 sammy-resized.pngを引数として渡すと、その名前の画像ファイルがプログラムの作業ディレクトリに保存されます。
次に、ファイルを保存して終了します。 ターミナルでプログラムを実行します。
node resizeImage.js
出力は表示されませんが、プロジェクトディレクトリにsammy-resized.pngという名前で作成された新しいイメージファイルが表示されます。
ローカルマシンでイメージを開きます。 幅150px、高さ97pxのサミーの画像が表示されます。
画像のサイズを変更できるようになったので、次に、サイズ変更した画像形式をpngからjpegに変換し、画像を圧縮して、作業ディレクトリに保存します。 これを行うには、toFormat()メソッドを使用します。これは、resize()メソッドの後にチェーンします。
強調表示されたコードを追加して、画像形式をjpegに変更し、圧縮します。
process_images / resizeImage.js
const sharp = require("sharp");
async function resizeImage() {
try {
await sharp("sammy.png")
.resize({
width: 150,
height: 97
})
.toFormat("jpeg", { mozjpeg: true })
.toFile("sammy-resized-compressed.jpeg");
} catch (error) {
console.log(error);
}
}
resizeImage();
resizeImage()機能では、シャープモジュールのtoFormat()方式で画像形式を変更し、圧縮します。 toFormat()メソッドの最初の引数は、画像を変換する画像形式を含む文字列です。 2番目の引数は、画像を拡張および圧縮する出力オプションを含むオプションのオブジェクトです。
画像を圧縮するには、ブール値を保持するmozjpegプロパティを画像に渡します。 trueに設定すると、sharpはデフォルトで mozjpeg を使用して、品質を犠牲にすることなく画像を圧縮します。 オブジェクトは、より多くのオプションを取ることもできます。 詳細については、シャープなドキュメントを参照してください。
注: toFormat()メソッドの2番目の引数に関して、各画像形式は異なるプロパティを持つオブジェクトを取ります。 たとえば、mozjpegプロパティは、JPEG画像でのみ受け入れられます。
ただし、他の画像形式には、quality、compression、losslessなどの同等のオプションがあります。 圧縮する画像形式で使用できるオプションの種類については、必ずドキュメントを参照してください。
次に、toFile()メソッドに別のファイル名を渡して、圧縮された画像をsammy-resized-compressed.jpegとして保存します。
次に、ファイルを保存して終了し、次のコマンドを使用してコードを実行します。
node resizeImage.js
出力はありませんが、画像ファイルsammy-resized-compressed.jpegがプロジェクトディレクトリに保存されます。
ローカルマシンでイメージを開くと、次のイメージが表示されます。
画像が圧縮されたら、ファイルサイズをチェックして、圧縮が成功したことを確認します。 ターミナルで、duコマンドを実行して、sammy.pngのファイルサイズを確認します。
du -h sammy.png
-hオプションは、キロバイト、メガバイトなどのファイルサイズを示す人間が読める形式の出力を生成します。
コマンドを実行すると、次のような出力が表示されます。
Output120K sammy.png
出力は、元の画像が120キロバイトであることを示しています。
次に、sammy-resized.pngのファイルサイズを確認します。
du -h sammy-resized.png
コマンドを実行すると、次の出力が表示されます。
Output8.0K sammy-resized.png
sammy-resized.pngは、120キロバイトから8キロバイト減少しています。 これは、サイズ変更操作がファイルサイズに影響を与えることを示しています。
次に、sammy-resized-compressed.jpegのファイルサイズを確認します。
du -h sammy-resized-compressed.jpeg
コマンドを実行すると、次の出力が表示されます。
Output4.0K sammy-resized-compressed.jpeg
sammy-resized-compressed.jpegは8キロバイトから4キロバイト減少し、4キロバイト節約され、圧縮が機能したことを示しています。
画像のサイズを変更し、形式を変更して圧縮したので、画像をトリミングしてグレースケールします。
ステップ4—画像のトリミングとグレースケールへの変換
このステップでは、画像をトリミングしてグレースケールに変換します。 トリミングは、画像から不要な領域を削除するプロセスです。 extend()メソッドを使用して、sammy.png画像をトリミングします。 その後、grayscale()メソッドをトリミングされた画像インスタンスにチェーンし、それをグレースケールに変換します。
テキストエディタでcropImage.jsを作成して開きます。
nano cropImage.js
cropImage.jsファイルに、次のコードを追加して画像を切り抜きます。
process_images / cropImage.js
const sharp = require("sharp");
async function cropImage() {
try {
await sharp("sammy.png")
.extract({ width: 500, height: 330, left: 120, top: 70 })
.toFile("sammy-cropped.png");
} catch (error) {
console.log(error);
}
}
cropImage();
cropImage()関数は、画像を読み取り、トリミングされた画像を返す非同期関数です。 tryブロック内で、sharpインスタンスが画像を読み取ります。 次に、インスタンスにチェーンされたシャープモジュールのextract()メソッドは、次のプロパティを持つオブジェクトを取得します。
width:トリミングする領域の幅。height:トリミングする領域の高さ。top:トリミングする領域の垂直位置。left:トリミングする領域の水平位置。
widthを500に設定し、heightを330に設定すると、シャープがトリミングする画像の上に透明なボックスを作成すると想像してください。 ボックスに収まる画像の一部は残り、残りはカットされます。
topおよびleftプロパティは、ボックスの位置を制御します。 leftを120に設定すると、ボックスは画像の左端から120ピクセルの位置に配置され、topを70に設定するとボックスは70ピクセルの位置に配置されます。画像の上端。
ボックス内に収まる画像の領域が抽出され、別の画像としてsammy-cropped.pngに保存されます。
ファイルを保存して終了します。 ターミナルでプログラムを実行します。
node cropImage.js
出力は表示されませんが、画像sammy-cropped.pngがプロジェクトディレクトリに保存されます。
ローカルマシンでイメージを開きます。 トリミングされた画像が表示されます。
画像をトリミングしたので、画像をグレースケールに変換します。 これを行うには、grayscaleメソッドをsharpインスタンスにチェーンします。 強調表示されたコードを追加して、画像をグレースケールに変換します。
process_images / cropImage.js
const sharp = require("sharp");
async function cropImage() {
try {
await sharp("sammy.png")
.extract({ width: 500, height: 330, left: 120, top: 70 })
.grayscale()
.toFile("sammy-cropped-grayscale.png");
} catch (error) {
console.log(error);
}
}
cropImage();
cropImage()関数は、シャープモジュールのgrayscale()メソッドをsharpインスタンスにチェーンすることにより、トリミングされた画像をグレースケールに変換します。 次に、画像をプロジェクトディレクトリにsammy-cropped-grayscale.pngとして保存します。
CTRL+Xを押して、ファイルを保存して終了します。
ターミナルでコードを実行します。
node cropImage.js
ローカルマシンでsammy-cropped-grayscale.pngを開きます。 これで、画像がグレースケールで表示されます。
画像をトリミングして抽出したので、画像を回転させてぼかします。
ステップ5—画像の回転とぼかし
このステップでは、sammy.png画像を33度の角度で回転させます。 また、回転した画像にガウスぼかしを適用します。 ガウスぼかしは、ガウス関数を使用して画像をぼかす手法であり、画像のノイズレベルと詳細を低減します。
テキストエディタでrotateImage.jsファイルを作成します。
nano rotateImage.js
rotateImage.jsファイルに、次のコードブロックを記述して、sammy.pngを33度の角度に回転させる関数を作成します。
process_images / rotateImage.js
const sharp = require("sharp");
async function rotateImage() {
try {
await sharp("sammy.png")
.rotate(33, { background: { r: 0, g: 0, b: 0, alpha: 0 } })
.toFile("sammy-rotated.png");
} catch (error) {
console.log(error);
}
}
rotateImage();
rotateImage()関数は、画像を読み取り、33度の角度に回転した画像を返す非同期関数です。 関数内で、sharpモジュールのrotate()メソッドは2つの引数を取ります。 最初の引数は、33度の回転角です。 デフォルトでは、シャープは回転した画像の背景を黒くします。 黒い背景を削除するには、2番目の引数としてオブジェクトを渡して、背景を透明にします。
オブジェクトには、RGBAカラーモデルを定義するオブジェクトを保持するbackgroundプロパティがあります。 RGBAは、赤、緑、青、およびアルファの略です。
r:赤色の強度を制御します。0から255の整数値を受け入れます。0は色が使用されていないことを意味し、255は最高で赤です。g:緑色の強度を制御します。0-255の整数値を受け入れます。0は緑色が使用されていないことを意味し、255は最高で緑色です。b:blueの強度を制御します。 また、0と255の間の整数値も受け入れます。0は青色が使用されていないことを意味し、255は最高で青色です。alpha:r、g、およびbプロパティで定義された色の不透明度を制御します。0または0.0は色を透明にし、1または1.1は色を不透明にします。
alphaプロパティを機能させるには、r、g、およびbの値を定義および設定していることを確認する必要があります。 r、g、bの値を0に設定すると、黒色になります。 透明な背景を作成するには、最初に色を定義する必要があります。次に、alphaを0に設定して透明にします。
次に、ファイルを保存して終了します。 ターミナルでスクリプトを実行します。
node rotateImage.js
プロジェクトディレクトリにsammy-rotated.pngが存在するか確認してください。 ローカルマシンで開きます。
33度の角度に回転した画像が表示されます。
次に、回転した画像をぼかします。 これは、blur()メソッドをsharpインスタンスにチェーンすることで実現できます。
画像をぼかすには、以下の強調表示されたコードを入力してください。
process_images / rotateImage.js
const sharp = require("sharp");
async function rotateImage() {
try {
await sharp("sammy.png")
.rotate(33, { background: { r: 0, g: 0, b: 0, alpha: 0 } })
.blur(4)
.toFile("sammy-rotated-blurred.png");
} catch (error) {
console.log(error);
}
}
rotateImage();
rotateImage()関数は、画像を読み取り、回転させ、画像にガウスぼかしを適用するようになりました。 シャープモジュールのblur()メソッドを使用して、画像にガウスぼかしを適用します。 このメソッドは、0.3と1000の間のシグマ値を含む単一の引数を受け入れます。 4を渡すと、シグマ値が4のガウスぼかしが適用されます。 画像がぼやけた後、ぼやけた画像を保存するためのパスを定義します。
スクリプトは、4のシグマ値で回転した画像をぼかします。 ファイルを保存して終了し、ターミナルでスクリプトを実行します。
node rotateImage.js
スクリプトを実行した後、ローカルマシンでsammy-rotated-blurred.pngファイルを開きます。 これで、回転した画像がぼやけて表示されます。
画像を回転させてぼかしたので、別の画像の上に合成します。
ステップ6—composite()を使用して画像を合成する
画像合成は、2つ以上の別々の画像を組み合わせて1つの画像を作成するプロセスです。 これは、さまざまな写真から最高の要素を取り入れた効果を作成するために行われます。 もう1つの一般的な使用例は、画像にロゴを透かしすることです。
このセクションでは、underwater.pngの上にsammy-transparent.pngを合成します。 これにより、サミーが海の奥深くを泳いでいるような錯覚が生じます。 画像を合成するには、composite()メソッドをsharpインスタンスにチェーンします。
ファイルcompositeImage.jsを作成し、テキストエディタで開きます。
nano compositeImages.js
次に、compositeImages.jsファイルに次のコードを追加して、2つの画像を合成する関数を作成します。
process_images / composeImages.js
const sharp = require("sharp");
async function compositeImages() {
try {
await sharp("underwater.png")
.composite([
{
input: "sammy-transparent.png",
top: 50,
left: 50,
},
])
.toFile("sammy-underwater.png");
} catch (error) {
console.log(error);
}
}
compositeImages()
compositeImages()関数は、最初にunderwater.png画像を読み取ります。 次に、引数として配列を受け取る、sharpモジュールのcomposite()メソッドをチェーンします。 配列には、sammy-transparent.pngイメージを読み取る単一のオブジェクトが含まれています。 オブジェクトには次のプロパティがあります。
input:処理された画像の上に合成したい画像のパスを取ります。 また、 Buffer 、 Uint8Array 、またはUint8ClampedArrayを入力として受け入れます。top:合成する画像の垂直位置を制御します。topを50に設定すると、underwater.png画像の上端からsammy-transparent.png画像が50ピクセルオフセットされます。left:合成する画像の水平位置を制御します。leftを50に設定すると、underwater.png画像の左端からsammy-transparent.pngが50ピクセルオフセットされます。
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—画像にテキストを追加する
このステップでは、画像にテキストを書き込みます。 執筆時点では、sharpには画像にテキストを追加するネイティブな方法がありません。 テキストを追加するには、まず、 Scalable Vector Graphics(SVG)を使用してテキストを描画するコードを記述します。 SVG画像を作成したら、compositeメソッドを使用して、画像をsammy.png画像と合成するコードを記述します。
SVGは、Web用のベクターグラフィックを作成するためのXMLベースのマークアップ言語です。 テキストや円や三角形などの形を描いたり、イラストやロゴなどの複雑な形を描いたりすることができます。 複雑な形状は、SVGコードを生成するInkscapeのようなグラフィックツールを使用して作成されます。 SVGシェイプは、品質を損なうことなく、任意のサイズにレンダリングおよびスケーリングできます。
addTextOnImage.jsファイルを作成してテキストエディタで開きます。
nano addTextOnImage.js
addTextOnImage.jsファイルに、次のコードを追加してSVGコンテナーを作成します。
process_images / addTextOnImage.js
const sharp = require("sharp");
async function addTextOnImage() {
try {
const width = 750;
const height = 483;
const text = "Sammy the Shark";
const svgImage = `
<svg width="${width}" height="${height}">
</svg>
`;
} catch (error) {
console.log(error);
}
}
addTextOnImage();
addTextOnImage()関数は、width、height、text、およびsvgImageの4つの変数を定義します。 widthは整数750を保持し、heightは整数483を保持します。 textは、文字列Sammy the Sharkを保持します。 これは、SVGを使用して描画するテキストです。
svgImage変数は、svg要素を保持します。 svg要素には、前に定義したwidth変数とheight変数を補間するwidthとheightの2つの属性があります。 svg要素は、指定された幅と高さに応じて透明なコンテナーを作成します。
svg要素に750のwidthと483と同じサイズになるようにしました。 X132X]。 これは、テキストをsammy.png画像の中央に表示するのに役立ちます。
次に、テキストグラフィックを描画します。 強調表示されたコードを追加して、SVGコンテナにSammy the Sharkを描画します。
process_images / addTextOnImage.js
async function addTextOnImage() {
...
const svg = `
<svg width="${width}" height="${height}">
<text x="50%" y="50%" text-anchor="middle" class="title">${text}</text>
</svg>
`;
....
}
SVG text要素には、x、y、text-anchor、およびclassの4つの属性があります。 xおよびyは、SVGコンテナーに描画するテキストの位置を定義します。 x属性はテキストを水平方向に配置し、y属性はテキストを垂直方向に配置します。
xを50%に設定すると、X軸のコンテナの中央にテキストが描画され、yを50%に設定すると、テキストが中央に配置されます。 SVG画像のy軸上。
text-anchorは、テキストを水平方向に揃えます。 text-anchorをmiddleに設定すると、指定したx座標の中央にテキストが配置されます。
classは、text要素のクラス名を定義します。 クラス名を使用して、CSSスタイルをtext要素に適用します。
${text}は、text変数に格納されている文字列Sammy the Sharkを補間します。 これは、SVG画像に描画されるテキストです。
次に、強調表示されたコードを追加して、CSSを使用してテキストのスタイルを設定します。
process_images / addTextOnImage.js
const svg = `
<svg width="${width}" height="${height}">
<style>
.title { fill: #001; font-size: 70px; font-weight: bold;}
</style>
<text x="50%" y="50%" text-anchor="middle" class="title">${text}</text>
</svg>
`;
このコードでは、fillはテキストの色を黒に変更し、font-sizeはフォントサイズを変更し、font-weightはフォントの太さを変更します。
この時点で、SVGでテキストSammy the Sharkを描画するために必要なコードを記述しました。 次に、SVGがテキストをどのように描画しているかを確認できるように、SVG画像をシャープのpngとして保存します。 それが完了したら、SVG画像をsammy.pngと合成します。
ハイライトされたコードを追加して、SVG画像をpngとしてシャープに保存します。
process_images / addTextOnImage.js
....
const svgImage = `
<svg width="${width}" height="${height}">
...
</svg>
`;
const svgBuffer = Buffer.from(svgImage);
const image = await sharp(svgBuffer).toFile("svg-image.png");
} catch (error) {
console.log(error);
}
}
addTextOnImage();
Buffer.from()は、SVGイメージからBufferオブジェクトを作成します。 バッファは、バイナリデータを格納するメモリ内の一時的なスペースです。
バッファオブジェクトを作成した後、バッファオブジェクトを入力としてsharpインスタンスを作成します。 画像パスに加えて、sharpは buffer 、 Uint9Array 、またはUint8ClampedArrayも受け入れます。
最後に、SVGイメージをプロジェクトディレクトリにsvg-image.pngとして保存します。
完全なコードは次のとおりです。
process_images / addTextOnImage.js
const sharp = require("sharp");
async function addTextOnImage() {
try {
const width = 750;
const height = 483;
const text = "Sammy the Shark";
const svgImage = `
<svg width="${width}" height="${height}">
<style>
.title { fill: #001; font-size: 70px; font-weight: bold;}
</style>
<text x="50%" y="50%" text-anchor="middle" class="title">${text}</text>
</svg>
`;
const svgBuffer = Buffer.from(svgImage);
const image = await sharp(svgBuffer).toFile("svg-image.png");
} catch (error) {
console.log(error);
}
}
addTextOnImage()
ファイルを保存して終了し、次のコマンドを使用してスクリプトを実行します。
node addTextOnImage.js
注:オプション2を使用してNode.jsをインストールした場合— NodeSource PPAまたはオプション3を使用してAptでNode.jsをインストールする—ノードバージョンマネージャーを使用してノードをインストールする[X181X ]そしてエラーfontconfig error: cannot load default config file: no such file: (null)が表示されたら、fontconfigをインストールしてフォント構成ファイルを生成します。
サーバーのパッケージインデックスを更新し、その後、apt installを使用してfontconfigをインストールします。
sudo apt update sudo apt install fontconfig
ローカルマシンでsvg-image.pngを開きます。 これで、透明な背景でレンダリングされたテキストSammy the Sharkが表示されます。
SVGコードがテキストを描画することを確認したので、テキストグラフィックをsammy.pngに合成します。
次の強調表示されたコードを追加して、SVGテキストグラフィックス画像をsammy.png画像に合成します。
process_images / addTextOnImage.js
const sharp = require("sharp");
async function addTextOnImage() {
try {
const width = 750;
const height = 483;
const text = "Sammy the Shark";
const svgImage = `
<svg width="${width}" height="${height}">
<style>
.title { fill: #001; font-size: 70px; font-weight: bold;}
</style>
<text x="50%" y="50%" text-anchor="middle" class="title">${text}</text>
</svg>
`;
const svgBuffer = Buffer.from(svgImage);
const image = await sharp("sammy.png")
.composite([
{
input: svgBuffer,
top: 0,
left: 0,
},
])
.toFile("sammy-text-overlay.png");
} catch (error) {
console.log(error);
}
}
addTextOnImage();
composite()メソッドは、svgBuffer変数からSVG画像を読み取り、それを上から0ピクセル、左端から0ピクセルに配置します。 sammy.png。 次に、合成画像をsammy-text-overlay.pngとして保存します。
ファイルを保存して閉じてから、次のコマンドを使用してプログラムを実行します。
node addTextOnImage.js
ローカルマシンでsammy-text-overlay.pngを開きます。 画像の上にテキストが追加されているはずです。
これで、composite()メソッドを使用して、SVGで作成されたテキストを別の画像に追加しました。
結論
この記事では、シャープなメソッドを使用してNode.jsで画像を処理する方法を学びました。 まず、画像を読み取るインスタンスを作成し、metadata()メソッドを使用して画像メタデータを抽出しました。 次に、resize()メソッドを使用して画像のサイズを変更しました。 その後、format()メソッドを使用して画像タイプを変更し、画像を圧縮しました。 次に、さまざまなシャープな方法を使用して、画像のトリミング、グレースケール、回転、およびぼかしを行いました。 最後に、composite()メソッドを使用して画像を合成し、画像にテキストを追加しました。
追加のシャープな方法の詳細については、シャープなドキュメントにアクセスしてください。 Node.jsの学習を継続する場合は、Node.jsシリーズのコーディング方法を参照してください。