【Node.js】 画像処理モジュールsharpの使い方を網羅してみました
更新日:2024/02/12
最近Node.jsで画像を処理する案件に遭遇しました。
その際にSharpというモジュールを使用しましたが、日本語の資料があまりないのでここでまとめておきます。
- 1sharpのインストール
- 2画像の読み込み
- 既存画像のロード
- 新規画像で初期化
- ピクセルデータを読み込む
- ストリームからの読み込み
- 複製を作成する
- 3フォーマット変換・保存
- 画像をファイル保存(出力)する
- 画像をバッファーに出力する
- ストリームに出力する
- フォーマット変換
- PNGに変換
- JPEGに変換
- WEBPに変換
- ピクセルデータに変換
- その他の変換
- 色空間(カラースペース)の変更
- 4画像サイズ(縦横)を変更する
- fitの適用例
- positionの適用例
- 5画像の合成
- 他の画像との合成
- blendの指定例
- 複数画像の合成
- 画像をタイル状に合成する
- 新規画像(無地)の合成
- ピクセルデータを作成して合成
- SVGデータの合成
- 6画像情報の取得
- 画像メタデータの取得
- ピクセル情報の取得
- 7画像処理
- 回転処理
- 垂直方向に反転
- 水平方向に反転
- アフィン変換をおこなう
- 画像をシャープにする
- 画像のノイズを除去
- 画像をぼかす
- 透明なチャネルとマージする
- ガンマ補正をおこなう
- ネガを生成
- 画像の輝度を正規化
- コンボリューション(たたみ込み)処理をおこなう
- しきい値処理をおこなう
- 画像間のビット演算をおこなう
- レベル調整をおこなう
- 画像をマトリクスで組み替える
- 明るさ、彩度、色相の回転で画像を変換
- 画像に色を付ける
- グレイスケールに変換
- 8チャネル操作
- アルファチャネルを削除する
- アルファチャネルを追加する
- チャネルを抜き出す
- チャネルを追加する
- 全チャネルをビット演算する
sharpのインストール
npmでsharpをインストールします。
npm install sharp
requireでロードします。
const sharp = require("sharp");
画像の読み込み
sharpの使い方を簡単に解説します。
既存画像のロード
sharp関数に画像へのパスを指定することで、既存画像を読み込みます。
const sharInstance = sharp( 画像パス );
返り値はsharpのインスタンスです。
sharpインスタンスメソッドの多くは、sharpインスタンスを返します。
下表のsharpインスタンスメソッドは引数でコールバックが省略されるとpromiseを返します。
Promiseを返すメソッド |
---|
metadata([callback]) |
stats([callback]) |
toFile(fileOut, [callback]) |
toBuffer([options], [callback]) |
Promiseを返すメソッドは、次のようにthen()やcatch()を使用できます。
thenで結果を受け取る
sharp( 画像パス )
.stats( )
.then( e=>{} )
.catch( e=>{} );
または、次のようにawaitで処理の終了を待つことができます。
awaitで終了を待つ
(async ()=>{
・・・なんらかの処理
const metadata = await sharp( 画像パス )
.stats( );
・・・後に続く処理
})();
新規画像で初期化
新規で画像を作成する場合は、次のような引数を渡します。
sharp( {
create: {
width: 250,
height: 80,
channels: 4,
background: { r: 255, g: 100, b: 100, alpha: 0.5 }
}
} )
.toFile( 出力パス );
出力結果は次のようになります。
■createのオブジェクトのプロパティ
createのオブジェクトは4つのプロパティを指定できます。
プロパティ名 | 意味 |
---|---|
width | 作成する無地画像の幅 |
height | 作成する無地画像の高さ |
channels | チャネルの数。3または4。赤、青、緑、アルファ値で4 |
background | 無地画像の色 |
backgroundは、r,g,b,alphaをプロパティに持つオブジェクトです。
それぞれ赤、青、緑、アルファ値に対応しています。
赤、青、緑は0から255で、数字が大きいほど濃くなります。
アルファ値は0から1.0までの小数で、ピクセルの透明度を表します。
0が透明です。
この他に、カラー名またはカラーコードでの指定もできます。
■カラー名で指定
background : "red"
■カラーコードで指定
background : "#ff00"
ピクセルデータを読み込む
他から取得したり、自分で作成したピクセルデータを読み込むことができます。
自分でピクセルデータを作成する場合は、Uint8Array()を使用します。
const LOGOHEIGHT = 80;
const LOGOHWIDTH = 250;
const LOGOCHANNEL = 4;
const LINEBYTS = LOGOHWIDTH * LOGOCHANNEL;
const LOGOBUFSIZE = LOGOHEIGHT * LINEBYTS;
// バッファを確保
const logoBuf = new Uint8Array( LOGOBUFSIZE ).fill(255);
const rgba = {r:255,g:100,b:100,alpha:.5 * 255};
// 一行目だけピクセルセット
for( let i = 0 ; i < LOGOHWIDTH ; i += 10 ){
const pos = i * LOGOCHANNEL;
logoBuf[pos] = rgba.r;
logoBuf[pos+1] = rgba.g;
logoBuf[pos+2] = rgba.b;
logoBuf[pos+3] = rgba.alpha;
}
// 一行目を1ピクセルずらしてコピー
let start = LINEBYTS + LOGOCHANNEL;
while( start < LOGOBUFSIZE ){
logoBuf.copyWithin( start , 0 , LINEBYTS);
start += LINEBYTS + LOGOCHANNEL;
}
// 下側半分の白地部分を透明化
start = LOGOHWIDTH * LOGOHEIGHT/2 * LOGOCHANNEL;
while( start < LOGOBUFSIZE ) {
if( logoBuf[start+1] === 255) logoBuf[start+3] = 0;
start += 4;
}
一つのピクセルは、赤、緑、青、アルファ値の4バイト使用します。
そのため画像一枚分は縦×横×4バイトになるので、その分だけ new Uint8Array( )で領域を確保し、白地にするために255で初期化しています。
そして、10ピクセル毎に斜め線を描くように、ピクセル値をセットしています。
なお、createのオブジェクトのアルファ値は0から1.0でしたが、ピクセル値の場合は0から255です。
次にsharpの第一引数にピクセルデータを、第二引数にオプション値を渡します。
オプション値は、rawオブジェクトをプロパティに持つオブジェクトです。
sharp( logoBuf ,
{
raw:{
width:LOGOHWIDTH,
height:LOGOHEIGHT,
channels:LOGOCHANNEL,
}
} )
.toFile( 出力パス );
rawオブジェクトはwidth、height、channelsをプロパティとして持ち、これらの値で、入力されたピクセルデータの縦横アルファ値を指定します。
出力結果は次のようになります。
※透明度がわかりやすいように、背景に色をつけています。
ストリームからの読み込み
ストリームから画像を読み込むこともできます。
複製を作成する
cloneメソッドを使用することで、sharpオブジェクトの複製を作成できます。
cloneメソッドを実行前に適用した処理(パラメーター)は、複製先に引き継がれます。
1で出力された画像
2で出力された画像
フォーマット変換・保存
画像をファイル保存(出力)する
toFileメソッドにファイルのパスを指定すると、画像を保存できます。
await sharp( 画像パス )
.toFile( 出力先画像パス , ( err , info ) =>{
if( err ) { エラー処理 }
});
出力形式は、画像パスの拡張子が考慮されます。
第二引数には、結果を受け取る関数を指定できます。
上の例では、読み込み直後に出力していますが、入力したファイルと出力ファイルは同じデータにはなりません。
例:
入力 image.png 115KB
出力 output.png 102KB ←サイズが減少した
一度画像を読み込んだ後、出力時に既定の品質で再フォーマットされているからです。
画像をバッファーに出力する
toBufferメソッドを使用すると、画像をバッファーに出力できます。
これにより、他のオブジェクトに画像データを渡すことができます。
上の例は、fsモジュール経由で画像データをファイル出力しています。
ストリームに出力する
ストリームに画像を出力することもできます。
const fs = require("fs");
const readableStream = fs.createReadStream( 画像パス );
const sharpData = sharp( )
.flip();
const writeStream = fs.createWriteStream( 出力先画像パス );
readableStream.on( "error" , err=>{
writeStream.end();
} );
readableStream
.pipe( sharpData )
.pipe( writeStream );
フォーマット変換
toFormatメソッドを使用することで、出力形式を強制します。
await sharp( 画像パス )
.toFormat( フォーマット名 )
.toFile( 出力先画像パス);
フォーマット名には次の値が使用できます。
"heic","heif","avif","jpeg","jpg","png","raw","tiff","webp","gif"
PNGに変換
pngメソッドを実行すると出力形式がPNGに変更されます。
品質等を指定できます。
await sharp( 画像パス )
.png( { progressive : true } )
.toFile( 出力先画像パス );
pngの引数は、次のプロパティを持つオブジェクトです。
省略可能です。
プロパティ | 意味 | 規定値 |
---|---|---|
progressive | プログレッシブ(インターレース)スキャンを使用する | false |
compressionLevel | zlib圧縮レベル 0から9 | 9 |
adaptiveFiltering | 適応行フィルタリングを使用するかどうか | false |
palette | アルファ透明度をサポートするパレットベースの画像にクオンタイズする。 | false |
quality | 与えられた品質を達成するために必要な最小の色数。 | 100 |
colours | パレットエントリの最大数。 | 256 |
colors | coloursのの代替スペル | 256 |
dither | フロイド-スタインバーグ誤差拡散のレベル。 | |
force | toFile()などの出力時PNG出力を強制。それ以外の場合は、入力形式を使用。 | true |
JPEGに変換
jpegメソッドを実行すると出力形式がJPEGに変換されます。
品質等を指定できます。
await sharp( 画像パス )
.jpeg( 引数 )
.toFile( 出力先画像パス );
jpegの引数は、次のプロパティを持つオブジェクトです。
省略可能です。
プロパティ | 意味 | 規定値 |
---|---|---|
quality | 品質。1から100 | 80 |
progressive | プログレッシブ(インターレース)スキャンを使用する | false |
chromaSubsampling | クロマサブサンプリングを防ぐには"4:4:4"に設定する。 | "4:2:0" |
optimiseCoding | ハフマン符号化テーブルを最適化する | true |
optimizeCoding | optimiseCodingの代替スペル | true |
trellisQuantisation | 格子量子化を適用する | false |
overshootDeringing | オーバーシュートデリンギングを適用 | false |
optimiseScans | プログレッシブスキャンを最適化し、プログレッシブを強制する | false |
optimizeScans | optimiseScansの代替スペル | false |
quantisationTable | 使用する量子化テーブル、整数0から8 | 0 |
quantizationTable | quantisationTableの代替スペル | 0 |
force | toFile()などの出力時JPEGを強制。それ以外の場合は、入力形式を使用。 | true |
WEBPに変換
webpメソッドを実行すると出力形式をWEBPに変更できます。
品質等を指定できます。
await sharp( 画像パス )
.webp( 引数 )
.toFile( 出力先画像パス );
webpの引数は、次のプロパティを持つオブジェクトです。
省略可能です。
プロパティ | 意味 | 規定値 |
---|---|---|
quality | 品質。1から100 | 80 |
alphaQuality | アルファレイヤーの品質。0から100 | 100 |
lossless | 可逆圧縮(ロスレス)モードを使用する | false |
nearLossless | ニアロスレスモードを使用する | false |
smartSubsample | 高品質クロマサブサンプリングを使用する | false |
reductionEffort | ファイルサイズ削減のCPU稼働レベル。0から6 | 4 |
pageHeight | アニメーション出力のページの高さ | false |
loop | アニメーションの繰り返し回数。0は無限回数 | 0 |
delay | アニメーションフレーム間の遅延のリスト(ミリ秒の配列) | |
force | toFile()などの出力時WEBPを強制。それ以外の場合は、入力形式を使用。 | true |
ピクセルデータに変換
rawメソッドを実行すると出力形式を生のピクセルデータに変更します。
1ピクセルは、ピクセルデータ内に符号なし8ビットデータをチャネル数分連続で所持します。
引数はありません。
await sharp( 画像パス )
.raw( )
.toFile( 出力先画像パス );
その他の変換
jpeg()などの他に、gif()、tiff()、avif()、heif()、raw()が用意されています。
使用頻度が少ないと思われるので、ここでは紹介しません。
色空間(カラースペース)の変更
toColourspaceまたはtoColorspaceメソッドを使用すると、出力時の色空間を指定できます。
第一引数に、色空間名を指定します。
例:"srgb"、"rgb"、 "cmyk"、 "lab"、"b-w"、"cmc"、"rgb16"、"grey16"、"hsv"等
await sharp( 画像パス )
.toColourspace( "cmyk" )
.toFile( 出力先画像パス );
画像サイズ(縦横)を変更する
画像の縦横サイズを変更するには、resizeメソッドを使用します。
await sharp( 画像パス )
.resize( 300 , 300 , { fit : "cover" } )
.toFile( 出力先画像パス );
resizeの第一・第二引数は幅、高さの順で指定します。
第三引数は省略可能で、次のプロパティを持つオブジェクトです。
プロパティ | 意味 | 規定値 |
---|---|---|
width | 第一引数と同じ。こちらが優先 | |
height | 第二引数と同じ。こちらが優先 | |
fit | widthとheightに合わせて画像を変更する方法。"cover", "contain", "fill", "inside", "outside"のどれか ※fitの適用例参照 | "cover" |
position | fitが"cover"または "contain"のときの位置。 "center","centre","north","east","south","west","northeast","southeast","southwest","northwest","top","right","bottom","left","right top","right bottom","left bottom","left top","entropy","attention"のどれか | "centre" |
background | fitが"contain"のときの背景色 | {r: 0, g: 0, b: 0, alpha: 1} |
kernel | 画像縮小に使用するカーネル "nearest","cubic","mitchel","lanczos2","lanczos3"のどれか | "lanczos3" |
withoutEnlargement | 現在の幅または高さが指定値よりも小さい場合は拡大しない。これはGraphicsMagickの ">"ジオメトリオプションと同等。 | false |
fastShrinkOnLoad | JPEGおよびWebPのロード時縮小機能をさらに活用する。これにより、一部の画像でわずかなモアレパターンが発生する可能性がある。 | true |
fitの適用例
次のサイズ100×100画像を、width70、height30でresizeを実行したときの適用結果です。
fitの値 | 適用結果 | 出力サイズ |
---|---|---|
cover | 70×30 | |
contain | 70×30 | |
fill | 70×30 | |
inside | 30×30 | |
outside | 70×70 |
positionの適用例
positionの値 | fit:"contain" | fit:"cover" | ||
---|---|---|---|---|
70×30 | 30×70 | 70×30 | 30×70 | |
center | ||||
centre | ||||
north | ||||
east | ||||
south | ||||
west | ||||
northeast | ||||
southeast | ||||
southwest | ||||
northwest | ||||
top | ||||
right | ||||
bottom | ||||
left | ||||
right-top | ||||
right-bottom | ||||
left-bottom | ||||
left-top | ||||
entropy | ||||
attention |
画像の合成
画像の合成は、sharp関数の戻り値に対してcompositeメソッドを実行します。
compositeメソッドの引数は、複数のオブジェクトの配列で指定します。
他の画像との合成
inputプロパティに画像ファイルへのパスを指定すると、画像を読み込んで合成できます
await sharp( 画像バス )
.composite([ {
input: 画像バス ,
blend: "over",
top:100,
left:100,
} ] )
.toFile( 出力先画像パス );
topとleftの代わりに、gravityが使用できます。
例:{ gravity : "east" }
値は、"center","centre","north","east","south","west","northeast","southeast","southwest","northwest"で、それぞれの方位(東西南北)に寄せることができます。
blendは、下地となる画像との合成方法を指定します。
次の値が使用できます。
"clear","source","over"(規定値),"in","out","atop","dest","dest-over","dest-in","dest-out","dest-atop","xor","add","saturate","multiply","screen","overlay","darken","lighten","colour-dodge","color-dodge","colour-burn","color-burn","hard-light","soft-light","difference","exclusion"
意味はこちらを参考にしてみてください。
下の例を見るとわかりますが、かけ合わせる画像の範囲ではなく、下地となる画像の全領域が対象となります。
場合によっては真っ黒になるので、注意が必要です。
blendの指定例
blendの例として、2つの画像を合成してみます。
【下地画像】
【合成画像】
blend値 | 合成結果 | blend値 | 合成結果 |
---|---|---|---|
clear | multiply | ||
source | screen | ||
over 規定値 | overlay | ||
in | darken | ||
out | lighten | ||
atop | colour-dodge | ||
dest | color-dodge | ||
dest-over | colour-burn | ||
dest-in | color-burn | ||
dest-out | hard-light | ||
dest-atop | soft-light | ||
xor | difference | ||
add | exclusion | ||
saturate |
複数画像の合成
次のようにオブジェクトを複数指定することで、複数画像を合成できます。
await sharp( 画像バス )
.composite([
{
input: 画像パス ,
gravity:"northwest",
}, {
input: 画像パス ,
gravity:"northeast",
blend:"overlay"
},{
input: 画像パス ,
gravity:"southwest",
blend:"colour-dodge"
},{
input: 画像パス ,
gravity:"southeast",
blend:"exclusion"
},
] )
.toFile( 出力先画像パス );
上の例は同じ画像ファイルを読み込んでいますが、異なるファイルでも問題ありません。
画像をタイル状に合成する
compositeに渡すオブジェクトにtitleプロパティを指定すると、合成画像をタイル表示できます。
まずはタイルなしバージョン。
await sharp( 画像パス )
.composite([ {
input: 合成画像パス,
top:20,
left:100,
} ])
.toFile( 出力先パス );
上のコードで、昔のけーちゃんみたいに河原でたそがれている男性の後ろ姿に、このサイトのロゴを貼り付けた結果がこちら。
次に、タイル表示してみます。
await sharp( 画像パス )
.composite([ {
input: 合成画像パス,
top:20,
left:100,
tile:true,
} ])
.toFile( 出力先パス );
タイル表示できましたが、間隔が狭すぎてごちゃっとしたイメージですね。
しかし、画像と画像の間隔指定ができないので、調整するにはタイル表示する画像を編集する必要があります。
あと注意する点が、topとleftの扱いです。
タイル表示なしの場合、下地画像の座標位置に、ロゴ画像を貼り付けています。
しかしタイル表示ありの場合、今回は資料を探すことができなかったのですが実行結果を見てみると、topとleftはタイル表示する画像上の座標位置をとして扱い、この位置と下地画像の左上を合わせているようです。
新規画像(無地)の合成
compositeに渡すオブジェクトのinputプロパティに、createプロパティを持っているオブジェクトを指定すると、無地画像を合成できます。
await sharp( 画像パス )
.composite([
{
input: {
create:{
width:250 , height:80 , channels:4,
background:{r:255,g:100,b:100,alpha:.5}
}
},
top:20 , left:100,
},
])
.toFile( 出力先パス );
createのオブジェクトについては、こちらを見てください。
例として、無地画像と画像をタイル状に合成するの画像を使用して、ロゴ画像の下にボックスを描画してみます。
await sharp( 画像パス )
.composite([ {
input: {
create:{
width:250,
height:80,
channels:4,
background:{r:255,g:100,b:100,alpha:.5}
}
},
top:20,
left:100,
},{
input: 合成画像パス,
top:20,
left:100,
tile:true,
} ])
.toFile( 出力先パス );
いい感じにタイトルっぽくなりました。
ピクセルデータを作成して合成
ピクセルデータの合成もできます。
合成するピクセルデータは、input及び、rawプロパティで指定します。
await sharp( 画像パス )
.composite([ {
input: logoBuf,
raw:{
width:LOGOHWIDTH,
height:LOGOHEIGHT,
channels:4,
},
top:20,
left:100,
},{
input: 合成画像パス,
top:20,
left:100,
tile:true,
} ])
.toFile( 出力先パス );
ここで読み込んでいるピクセルデータは、ピクセルデータを読み込むで作成しているものです。
結果は次のようになります。
わかりにくいですが、ロゴの下半分だけ透過しています。
SVGデータの合成
SVGデータはBuffer.fromメソッドを経由して、compositeメソッドに渡します。
text-to-svgモジュールを使用して文字列を描画することもできます。
const TextToSVG = require("text-to-svg");
const outputText = "お腹すいたなぁ・・・";
const svgOptions = {x: 0, y: 0, fontSize: 40, anchor: "left top", attributes: {fill: "white", stroke: "black"}};
const svgBuffer = TextToSVG.loadSync().getSVG(outputText, svgOptions);
sharp( 画像バス )
.composite([ {
input: Buffer.from( svgBuffer ),
top:200,
left:80,
},{
input: 合成画像パス,
top:20,
left:100,
} ])
.toFile( 出力先パス );
結果は次のようになります。
文字の合成については別の記事で紹介しているので、そちらを見てください。
【Node.js】 既存画像に文字を描画し圧縮して出力する
画像情報の取得
画像メタデータの取得
metadataメソッドを使用すると、画像が持っているメタデータを取得できます。
sharp( 画像バス )
.metadata( (err,metadata) =>{
if( err ) { エラー処理 }
console.log( metadata);
});
Promiseを使用すると、次のようになります。
sharp( 画像バス )
.metadata( )
.then( metadata =>{
console.log( metadata);
},err => {
エラー処理
});
■出力結果
{
format: 'jpeg',
width: 500,
height: 333,
space: 'srgb',
channels: 3,
depth: 'uchar',
density: 72,
chromaSubsampling: '4:2:0',
isProgressive: true,
hasProfile: false,
hasAlpha: false
}
ピクセル情報の取得
statsメソッドを使用すると、画像のピクセル情報を取得できます。
sharp( 画像バス )
.stats( (err,metadata) =>{
if( err ) { エラー処理 }
console.log( metadata);
});
Promiseを使用すると、次のようになります。
sharp( 画像バス )
.stats( )
.then( metadata =>{
console.log( metadata);
},err => {
エラー処理
});
■出力結果
{
channels: [
{
min: 1,
max: 255,
sum: 28100568,
squaresSum: 5649201036,
mean: 168.7721801801802,
stdev: 73.79105130026998,
minX: 302,
minY: 304,
maxX: 92,
maxY: 0
},
{
min: 0,
max: 255,
sum: 28473774,
squaresSum: 5856332986,
mean: 171.01365765765766,
stdev: 76.99049020788779,
minX: 290,
minY: 272,
maxX: 18,
maxY: 0
},
{
min: 0,
max: 255,
sum: 26903409,
squaresSum: 5486401443,
mean: 161.58203603603604,
stdev: 82.72029222291602,
minX: 200,
minY: 182,
maxX: 28,
maxY: 0
}
],
isOpaque: true,
entropy: 7.19947114540264,
sharpness: 2.462638259245144,
dominant: { r: 248, g: 248, b: 248 }
}
画像処理
ここでは次の画像を例として、sharpで実行できる画像処理を紹介します。
画像サイズ:300×199
なお、これらのメソッドは各パラメータをセットするだけです。
処理は後で行われます。
そのため、rotateを複数呼び出すなどしても、回転処理が適用されるのは基本的に一度だけです。
回転処理
rotateメソッドを使用すると、画像を回転できます。
第一引数に角度、オプションで第二引数に背景色を指定できます。
sharp( 画像パス )
.rotate( 317 ,
{
background:{ r:200,g:150,b:150,alpha:1}
}
)
.toFile( 出力パス )
画像サイズそのままで回転するので、出力サイズは355×350と大きくなりました。
垂直方向に反転
flipメソッドで、垂直方向に反転するかどうか指定できます。
第一引数に反転するかどうかの真偽値を指定します。
省略時はtrueです。
水平方向に反転
flipメソッドで、垂直方向に反転するかどうか指定できます。
第一引数に反転するかどうかの真偽値を指定します。
省略時はtrueです。
アフィン変換をおこなう
affineメソッドを使用することで、画像のピクセル位置をアフィン変換で移動します。
第一引数は要素数4の配列または2×2の2次元配列です。
この配列により、次のように変換されます。(配列は2次元配列とする)
変換後X = 配列[0][0] * (x + idx) + 配列[0][1] * (y + idy) + odx
変換後Y = 配列[1][0] * (x + idx) + 配列[1][1] * (y + idy) + ody
idx、idy、odx、odyはオプションで指定でき、デフォルトで0です。
sharp( 画像パス )
.affine([[1, 0.5], [0.2, 0.4]], {
background: "#f0a0a0",
})
.toFile( 出力先画像パス );
■affineのオプション
プロパティ名 | 意味 | 初期値 |
---|---|---|
background | 背景色 | "#000000" |
idx | 入力水平オフセット | 0 |
idy | 入力垂直オフセット | 0 |
odx | 出力水平オフセット | 0 |
ody | 出力垂直オフセット | 0 |
interpolator | 補間オプションの変更 | sharp.interpolators.bicubic |
■sharp.interpolatorsのプロパティ
オプションinterpolatorには、次の値を使用できます。
sharp.interpolators.nearest
http://en.wikipedia.org/wiki/Nearest-neighbor_interpolation
sharp.interpolators.bilinear
http://en.wikipedia.org/wiki/Bilinear_interpolation
sharp.interpolators.bicubic(デフォルト)
http://en.wikipedia.org/wiki/Bicubic_interpolation
sharp.interpolators.locallyBoundedBicubic
https://github.com/jcupitt/libvips/blob/master/libvips/resample/lbb.cpp#L100
sharp.interpolators.nohalo
http://eprints.soton.ac.uk/268086/
sharp.interpolators.vertexSplitQuadraticBasisSpline
https://github.com/jcupitt/libvips/blob/master/libvips/resample/vsqbs.cpp#L48
画像をシャープにする
sharpenメソッドを使用すると、画像をシャープにできます。
このメソッドは引数を3つ受け取ります。
引数なしで実行すると、穏やかなシャープネスを高速で実行する。
順番 | 引数名 | 意味 | 規定値 |
---|---|---|---|
1 | sigma | ガウスマスクのシグマ。 0.01から10000。またはマイルドなシャープを実行するか(真偽値)。 | |
2 | flat | 「平らな」領域に適用するシャープネスのレベル。 0から10000。 | 1.0 |
3 | jagged | 「ギザギザ」の領域に適用するシャープネスのレベル。 0から10000。 | 2.0 |
sharp( 画像パス )
.sharpen(100, 100, 0)
.toFile( 出力先画像パス );
画像のノイズを除去
medianメソッドを使用すると、メディアンフィルタで画像のノイズを除去します。
このメソッドはマスクサイズを引数として受け取ります。
引数は省略でき、規定値は3です。
sharp( 画像パス )
.median(10)
.toFile( 出力先画像パス );
画像をぼかす
blurメソッドを使用すると、画像をぼかすことができます。
このメソッドはガウスマスクのシグマを表す0.3から1000の値を引数として受け取ります。
引数は省略すると、高速で穏やかなぼかしを実行します。
sharp( 画像パス )
.blur(10)
.toFile( 出力先画像パス );
透明なチャネルとマージする
flattenメソッドは、アルファ透明チャンネルがある場合にbackgroundとマージします。
このメソッドはbackgroundプロパティ値を持つオブジェクトを引数として受け取ります。
引数は省略すると、{r:0,g:0,b:0}が規定値となります。
sharp( 画像パス.png )
.toFile( {background:"blue"} )
.toFile( 出力先画像パス.png );
※不透明化後、pngで出力したものを入力画像として使用しています。
ガンマ補正をおこなう
gammaメソッドを使用すると、ガンマ補正をおこなうことができます。
このメソッドは引数を2つ受け取ります。
第二引数が省略された場合、第一引数は入力および出力ガンマ値の両方の設定値となります。
第二引数が指定された場合、第一引数が入力、第二引数が出力ガンマ値となります。
引数が指定されなかった場合は、規定値が2.2となります。
sharp( 画像パス )
.gamma( 1 , 3 )
.toFile( 出力先画像パス );
ネガを生成
negateメソッドを使用すると、ネガを生成かどうか指定できます。
第一引数にネガを生成するかどうかの真偽値を指定します。
省略時はtrueです。
sharp( 画像パス )
.negate( )
.toFile( 出力先画像パス );
画像の輝度を正規化
normaliseメソッドおよびnormalizeメソッドは、ダイナミックレンジ全体をカバーするように輝度を伸ばすことで、出力画像のコントラストを強化します。
第一引数にネガを正規化するかどうかの真偽値を指定します。
省略時はtrueです。
sharp( 画像パス )
.normalise( )
.toFile( 出力先画像パス );
コンボリューション(たたみ込み)処理をおこなう
convolveメソッドは、指定された情報をもとにたたみ込み処理をおこないます。
このメソッドは、プロパティを5つもつオブジェクトを引数として受け取ります。
順番 | プロパティ名 | 意味 | 規定値 |
---|---|---|---|
1 | kernel | カーネル値を含む要素数width * heightの配列 | |
2 | width | kernelの幅(ピクセル単位) 3から1001 | |
3 | height | kernelの高さ(ピクセル単位) 3から1001 | |
4 | scale (省略可) | kernelのスケール(ピクセル単位) | kernelの要素の合計 |
5 | offset (省略可) | kernelのオフセット(ピクセル単位) | 0 |
※kernel.length === width * height を満たす必要があります。
sharp( 画像パス )
.convolve({
width:3,
height:3,
kernel:[ 1 , -2 , -1 , 1 , -1 , 0 , 2 , -1 , 1],
})
.toFile( 出力先画像パス );
しきい値処理をおこなう
thresholdメソッドは、しきい値以上のピクセル値に255をセット、または現在の値を保持し、それ以外は0をセットします。
このメソッドは、2つの引数を受け取ります。
第一引数は、しきい値です。0,から255で指定します。
第二引数は省略可能で、greyscaleまたはgrayscaleプロパティを持つオブジェクトを指定します。
greyscaleまたはgrayscaleがtrueのときピクセル値に255がセットされます。
falseのときは、色が保持されます。
規定値は、trueです。
greyscale : true(指定なし)
greyscale : false
画像間のビット演算をおこなう
booleanメソッドは、指定された画像とビット演算をおこないます。
このメソッドは3つの引数を持ちます。
順番 | 引数名 | 意味 | 規定値 |
---|---|---|---|
1 | operand | 演算対象の画像。パスや画像バッファー、ピクセルデータなどで指定 | |
2 | operator | 演算方法。"and"、"or"、 "eor"のどれか | |
3 | options | 入力がピクセルデータのときにrawオブジェクトをプロパティに持つオブジェクトを指定 |
sharp( 画像パス )
.boolean( 演算用画像 , "and" )
.toFile( 出力先画像パス );
次の2枚をビット演算します。
2枚目は、白地で1枚目と同サイズです。
■結果
レベル調整をおこなう
linearメソッドは、一次方程式a * input + bを画像に適用し、レベル調整をおこないます。
inputは、ピクセルの値。
aは第一引数で、規定値は1.0。
bは第二引数で、規定値は0.0です。
両引数とも、省略可能です。
sharp( 画像パス )
.linear( 2 , -25 )
.toFile( 出力先画像パス );
画像をマトリクスで組み替える
recombメソッドは、3×3の配列で画像を組み替えます。
配列は第一引数で指定します。
sharp( 画像パス )
.recomb( [
[ 1.2222 , 0.3333 , 0.12345 ],
[ 0.1234 , 1.2345 , 0.44444 ],
[ 1.0101 , 0.2020 , 1.30303 ]
])
.toFile( 出力先画像パス );
明るさ、彩度、色相の回転で画像を変換
modulateメソッドは、明るさ、彩度、色相の回転を使用して画像を変換します。
引数は、3つのプロパティを持つオブジェクトを一つ指定します。
順番 | 引数名 | 意味 | 規定値 |
---|---|---|---|
1 | brightness | 明るさに乗算する値 | 1 |
2 | saturation | 彩度に乗算する値 | 1 |
3 | hue | 色相の回転角度 | 0 |
sharp( 画像パス )
.modulate({
brightness:1.3,
hue:126,
})
.toFile( 出力先画像パス );
画像に色を付ける
tintメソッドは、輝度を維持しながら、指定した色の彩度を使用して画像に色を付けます。
引数は、色を表す値です。
sharp( 画像パス )
.tint("blue")
.toFile( 出力先画像パス );
グレイスケールに変換
greyscaleまたはgrayscaleメソッドを使用すると、8ビットのグレイスケールに変換するかどうかを指定できます。。
第一引数に変換するかどうかの真偽値を指定します。
省略時はtrueです。
sharp( 画像パス )
.greyscale( )
.toFile( 出力先画像パス );
チャネル操作
処理は後でまとめて行われるため、処理をする順番はあまり意味がありません。
ensureAlphaメソッドでアルファチャネルを追加した後、extractChannelメソッドでアルファチャネルを抜き出そうとしてもエラーが出る可能性があります。
アルファチャネルを削除する
removeAlphaメソッドは、アルファチャネルを削除します。
sharp( 画像パス.png )
.removeAlpha( )
.toFile( 出力先画像パス.png );
半透明な
画像
アルファチャネル削除
したため透明解除
アルファチャネルを追加する
ensureAlphaメソッドは、アルファチャネルを追加して、255をセットします。
次の例は、jpg画像を読み込み不透明化し、pngで出力しています。
チャネルを抜き出す
extractChannelは指定したチャネルを抜き出し、他のチャネルを同じ値に置き換えます。
チャネルは第一引数に"red"、 "green"、 "blue"、 "alpha"で指定します。
sharp( 画像パス )
.extractChannel("red")
.toFile( 画像パス );
チャネルを追加する
joinChannelは指定した画像データのチャネルを追加します。
複数チャネルがある場合でも、単純に追加されます。
例えば元となる画像のチャネル数が3で、追加指定した画像のチャネル数が4なら合計で7チャネルになります。
次のコードは、追加する画像の赤チャネルを抜き出し、元となる画像のアルファチャネルに追加しています。
sharp( 追加する画像のパス )
.extractChannel("red")
.toColourspace("b-w")
.raw()
.toBuffer((err, data, info)=>{
sharp( 画像パス )
.joinChannel( data , { raw:{width:info.width,height:info.height,channels:1 }} )
.toFile( 出力先パス.png );
});
toColourspace("b-w")でチャネル数を1にしているため、toBufferで受け取るチャネルが一つのみになります。
■追加する画像
■結果
全チャネルをビット演算する
bandboolは画像内の全チャネルをビット演算子、結果を全チャネルにセットします。
チャネルは第一引数に"and"、 "or"、 "eor"で指定します。
sharp( 画像パス )
.toFile("and")
.toFile( 画像パス );
更新日:2024/02/12
関連記事
スポンサーリンク
記事の内容について
こんにちはけーちゃんです。
説明するのって難しいですね。
「なんか言ってることおかしくない?」
たぶん、こんなご意見あると思います。
裏付けを取りながら記事を作成していますが、僕の勘違いだったり、そもそも情報源の内容が間違えていたりで、正確でないことが多いと思います。
そんなときは、ご意見もらえたら嬉しいです。
掲載コードについては事前に動作確認をしていますが、貼り付け後に体裁を整えるなどをした結果動作しないものになっていることがあります。
生暖かい視線でスルーするか、ご指摘ください。
ご意見、ご指摘はこちら。
https://note.affi-sapo-sv.com/info.php
このサイトは、リンクフリーです。大歓迎です。