サイト画像を正方形(透過の余白付き)にする
サイト画像(サイトメニューやパンくずリストのアイコン)に縦横比が 1 対 1 でない画像を使うと、保存される画像は正方形になりません。このページは、透過の余白を付けて正方形にする本体改修の設計メモです。本体の標準機能ではありません。
前提にした現行実装
保存されるサイズ
サイト画像をアップロードすると、ImageData が 3 つのサイズを作って PNG で保存します(ImageData.cs、L179-L187)。サイズは General.json で決まります(General.json)。
| 種類 | パラメータ | 既定(px) |
|---|---|---|
Regular | ImageSizeRegular | 460 |
Thumbnail | ImageSizeThumbnail | 50 |
Icon | ImageSizeIcon | 26 |
Logo(テナントのロゴ) | ImageSizeLogo | 32 |
保存先は BinaryStorage.json の SiteImageProvider(未設定なら Provider)で決まり、Binaries テーブルか、ストレージプロバイダ(ローカルの SiteImage/{SiteId}_{サイズ}.png など)です(BinaryStorage.cs)。
リサイズの計算
ReSize(SizeTypes) は、横長の画像(とロゴ)は高さ、それ以外は幅が目標のサイズになる倍率で縮めます(ImageData.cs)。短い辺を目標に合わせるので、長い辺ははみ出します。中央に置くための x・y も計算していますが、GetImage は Resize(width, height) を呼ぶだけで、この 2 つを使っていません(ImageData.cs)。
1000×500 の画像を Regular(460)にする場合
倍率 = 460 / 500 = 0.92
出力 = 920×460(正方形にならない)GetImage は元の画像(Data)を Mutate で書き換えるので、Regular → Thumbnail → Icon の順に、前の結果をさらに縮めていきます。
改修方針
SixLabors.ImageSharp(1.5.8.1 は 3.1.12、Implem.Pleasanter.csproj)の ResizeMode.Pad を使います。縦横比を保ったまま長い辺を目標に合わせ、足りない部分を PadColor で埋めて中央に置きます。
private Image ReSize(SizeTypes sizeType)
{
var size = Size(sizeType);
if (Data.Width == size && Data.Height == size) return Data;
return sizeType == SizeTypes.Logo
? GetImageScaled(size) // ロゴは現行どおり(高さ基準・余白なし)
: GetImagePadded(size);
}
private Image GetImagePadded(int size)
{
Data.Mutate(ctx => ctx.Resize(new ResizeOptions
{
Size = new Size(size, size),
Mode = ResizeMode.Pad,
PadColor = Color.Transparent
}));
return Data;
}
private Image GetImageScaled(int size)
{
var rate = (double)size / Data.Height;
Data.Mutate(ctx => ctx.Resize(
(Data.Width * rate).ToInt(),
(Data.Height * rate).ToInt()));
return Data;
}1000×500 の画像を 460 の正方形にする場合
長い辺(幅)を 460 に → 460×230
上下に 115 px ずつ透過の余白 → 460×460- 保存は PNG なので透過はそのまま残ります。
- Markdown に貼った画像の縮小に使う
ReSize(decimal?)は正方形にする必要がないので変えません(ImageData.cs)。GetImage(width, height, x, y)はこちらで使っているので残します。 - 変えるのは
Libraries/Images/ImageData.csの 1 ファイルです。CodeDefiner の生成対象ではありません。 - 改修後にアップロードした画像から正方形になります。既存のサイト画像は、アップロードし直すまで変わりません。
画像が正方形になると、サイトメニューのアイコンに付いている border-radius: 8px の角丸もそのまま効き、border-radius: 50% にすれば円になります。