まず、ふざけるなと言いたいんですが笑
インスタグラムのグリッドのアスペクト比が正方形から3:4に変わったことで
さまざまなインスタのグリッドが崩れています。

こんなかんじになっちゃってる…(ちなみにこれは弊社運営の飲食店です.)
正方形で作っていた人が多いですよね。
先週からABテストで一部のユーザは3:4になっているようです。
グリッドを生成するアプリも正方形で分割しているので被害を受けている人たちがいるのではないかと思います。
今からアプリをまだダウンロードするのか、そもそもそんなアプリない…。
またはサーバーサイドで縦長で分割するツールを作るのか…
かなりだるいですよね?
しかもABテストなので元に戻るかもしれないし
なんかおかしいなってことでやたらアクセスするからアクセスカウト増えて「成功」ってインスタグラム側が判断しそうだし。
もともと4:5を推奨していたという話も含めて4:5や3:4の話でこんな記事たちがあります
1. 【保存版】Instagram(インスタグラム) 投稿画像・動画サイズ
記事では、Instagramの公式推奨サイズとして縦長の画像が最大4:5の比率でトリミングされることについて説明されています。
2. Instagram投稿に最適な画像サイズとは?ストーリーズ、リール
縦長の画像は最大4:5の比率でしか投稿できないことが説明されています。スマートフォンで撮影された写真が、この変更に合わせて最適化される背景も解説されています。
3. 【SNS最新情報】インスタの投稿が「縦長」に!「3:4」比率で
投稿比率の変更による縦長写真の最適化について、スマートフォンユーザーの利用傾向に基づいた詳細が書かれています。
4. 【最新版】インスタの画像や動画サイズを解説!変更方法や
Instagram投稿で縦長サイズが4:5まで対応していることについて記載されており、変更方法や解像度の推奨値についても触れられています。
5. 【2024年最新】Instagramのフィード投稿に最適な画像サイズ完全
幅320~1080ピクセルの画像に対応するアスペクト比として、1:1から4:5が推奨されていることが詳しく解説されています。
わりと事件ではないかなと
そこでインスタグラムの新しい比率にしてくれる分割ツールを作りました。
サーバーとかどうでもよいのでhtmlとjsだけでぱっとやれないかなという人のために
以下が全文のコードです
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>画像分割ツール</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
</head>
<body class="bg-light">
<div class="container py-5">
<h1 class="text-center mb-4">画像分割ツール</h1>
<form id="splitForm" class="bg-white p-4 rounded shadow-sm">
<div class="mb-3">
<label for="image" class="form-label">画像をアップロード:</label>
<input type="file" id="image" class="form-control" accept="image/*" required>
</div>
<div class="mb-3">
<label for="gridSize" class="form-label">分割サイズ:</label>
<select id="gridSize" class="form-select">
<option value="3x2">3×2</option>
<option value="3x3">3×3</option>
<option value="3x4">3×4</option>
<option value="2x2">2×2</option>
<option value="2x3">2×3</option>
<option value="2x4">2×4</option>
<option value="4x2">4×2</option>
<option value="4x3">4×3</option>
<option value="4x4">4×4</option>
</select>
</div>
<button type="submit" class="btn btn-primary w-100">分割</button>
</form>
<div id="imagePreview" class="mt-5 d-flex flex-wrap justify-content-start"></div>
<canvas id="canvas" style="display: none;"></canvas>
</div>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jszip/3.10.1/jszip.min.js"></script>
<script>
document.getElementById('splitForm').addEventListener('submit', async (event) => {
event.preventDefault();
const imageInput = document.getElementById('image');
const gridSize = document.getElementById('gridSize').value.split('x');
const imagePreview = document.getElementById('imagePreview');
const rows = parseInt(gridSize[1], 10);
const cols = parseInt(gridSize[0], 10);
if (!imageInput.files[0]) {
alert('画像をアップロードしてください。');
return;
}
const file = imageInput.files[0];
const img = new Image();
img.src = URL.createObjectURL(file);
img.onload = () => {
const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');
// Calculate tile dimensions with a fixed aspect ratio of 3:4
const aspectRatio = 3 / 4;
const tileWidth = Math.min(img.width / cols, img.height / rows * aspectRatio);
const tileHeight = tileWidth / aspectRatio;
let images = [];
imagePreview.innerHTML = ""; // Clear previous previews
for (let row = 0; row < rows; row++) {
const rowDiv = document.createElement('div');
rowDiv.className = "d-flex justify-content-center mb-3 w-100";
for (let col = 0; col < cols; col++) {
canvas.width = tileWidth;
canvas.height = tileHeight;
ctx.drawImage(
img,
col * tileWidth, row * tileHeight, // 元画像から切り取る位置
tileWidth, tileHeight, // 元画像から切り取るサイズ
0, 0, // 新しいキャンバス上の描画開始位置
tileWidth, tileHeight // 新しいキャンバス上の描画サイズ
);
// Export as high-quality PNG
const dataUrl = canvas.toDataURL('image/png', 1.0);
images.push(dataUrl);
const colDiv = document.createElement('div');
colDiv.className = "text-center me-3";
colDiv.innerHTML = `<img src="${dataUrl}" alt="Tile" class="img-thumbnail mb-2"><br><small>tile_${images.length}.png</small>`;
rowDiv.appendChild(colDiv);
}
imagePreview.appendChild(rowDiv);
}
downloadImages(images);
};
});
function downloadImages(images) {
const zip = new JSZip();
const folder = zip.folder("split_images");
images.forEach((image, index) => {
const base64Data = image.replace(/^data:image\/png;base64,/, "");
folder.file(`tile_${index + 1}.png`, base64Data, { base64: true });
});
zip.generateAsync({ type: "blob" }).then((content) => {
const a = document.createElement('a');
a.href = URL.createObjectURL(content);
a.download = "split_images.zip";
a.click();
});
}
</script>
</body>
</html>
アクセスするとUIはこんな感じ

で、アップすると…

そして画面にも

この数字の順番に投稿すればうまくはまるると思います。
ちなみにこの画像は最近Newsweekに取り上げられたのでその画像です。
ツール欲しい人は連絡ください。
10分で作れたので、あげます。
後このコードは画質が悪くなりますのでcanvas.toDataURL(‘image/png’, 1.0) いれましたが、
これ以上の画質はjsだけだとどうだろうな…
ベースには良いコードかと思います。