CSS及びドキュメントを修正
This commit is contained in:
parent
09c26b0a4d
commit
1f67a85881
@ -74,3 +74,17 @@ RUN docker-php-ext-configure gd \
|
||||
&& docker-php-ext-install gd
|
||||
|
||||
```
|
||||
|
||||
|
||||
### ImageMagickの対応
|
||||
|
||||
```Dockerfile
|
||||
RUN apk add --no-cache \
|
||||
imagemagick \
|
||||
imagemagick-dev \
|
||||
libheif \
|
||||
|
||||
|
||||
RUN pecl install imagick \
|
||||
&& docker-php-ext-enable imagick
|
||||
```
|
@ -1,8 +1,4 @@
|
||||
<?php
|
||||
// ImageEdit.php
|
||||
// 画像をリサイズして変換するPHPWEBアプリケーション
|
||||
// 画像の最大サイズを指定し、JPEGまたはPNG形式に変換します
|
||||
|
||||
function processImage($file, $maxWidth = 400, $maxHeight = 400, $format = 'jpeg')
|
||||
{
|
||||
$srcImage = @imagecreatefromstring(file_get_contents($file['tmp_name']));
|
||||
@ -13,20 +9,17 @@ function processImage($file, $maxWidth = 400, $maxHeight = 400, $format = 'jpeg'
|
||||
$origWidth = imagesx($srcImage);
|
||||
$origHeight = imagesy($srcImage);
|
||||
|
||||
// サイズ比率を維持してリサイズ
|
||||
$scale = min($maxWidth / $origWidth, $maxHeight / $origHeight, 1);
|
||||
$newWidth = (int) ($origWidth * $scale);
|
||||
$newHeight = (int) ($origHeight * $scale);
|
||||
|
||||
$dstImage = imagecreatetruecolor($newWidth, $newHeight);
|
||||
|
||||
// 透過画像(PNGなど)の背景を白にする
|
||||
$white = imagecolorallocate($dstImage, 255, 255, 255);
|
||||
imagefilledrectangle($dstImage, 0, 0, $newWidth, $newHeight, $white);
|
||||
|
||||
imagecopyresampled($dstImage, $srcImage, 0, 0, 0, 0, $newWidth, $newHeight, $origWidth, $origHeight);
|
||||
|
||||
// 出力
|
||||
ob_start();
|
||||
if ($format === 'png') {
|
||||
imagepng($dstImage);
|
||||
@ -45,42 +38,56 @@ function processImage($file, $maxWidth = 400, $maxHeight = 400, $format = 'jpeg'
|
||||
?>
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
|
||||
<html lang="ja">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>画像変換ツール</title>
|
||||
<!-- Bootstrap 5 CDN -->
|
||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<h1>画像変換ツール</h1>
|
||||
<form method="post" enctype="multipart/form-data">
|
||||
<label>画像を選択:</label><br>
|
||||
<input type="file" name="image" accept="image/*" required><br><br>
|
||||
<label>変換形式:</label>
|
||||
<select name="format">
|
||||
<option value="jpeg">JPEG</option>
|
||||
<option value="png">PNG</option>
|
||||
</select><br><br>
|
||||
<label>最大サイズ(幅×高さ):</label>
|
||||
<input type="number" name="maxWidth" value="400" min="1"> ×
|
||||
<input type="number" name="maxHeight" value="400" min="1"><br><br>
|
||||
<button type="submit">変換</button>
|
||||
</form>
|
||||
<div class="container py-5">
|
||||
<div class="card shadow">
|
||||
<div class="card-body">
|
||||
<h1 class="card-title mb-4">画像変換ツール</h1>
|
||||
<form method="post" enctype="multipart/form-data" class="mb-4">
|
||||
<div class="mb-3">
|
||||
<label for="image" class="form-label">画像を選択:</label>
|
||||
<input type="file" name="image" id="image" accept="image/*" class="form-control" required>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="format" class="form-label">変換形式:</label>
|
||||
<select name="format" id="format" class="form-select">
|
||||
<option value="jpeg">JPEG</option>
|
||||
<option value="png">PNG</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label class="form-label">最大サイズ(幅×高さ):</label>
|
||||
<div class="d-flex gap-2">
|
||||
<input type="number" name="maxWidth" value="400" min="1" class="form-control" placeholder="幅">
|
||||
<span class="align-self-center">×</span>
|
||||
<input type="number" name="maxHeight" value="400" min="1" class="form-control" placeholder="高さ">
|
||||
</div>
|
||||
</div>
|
||||
<button type="submit" class="btn btn-primary">変換</button>
|
||||
</form>
|
||||
|
||||
<?php
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_FILES['image'])) {
|
||||
$result = processImage($_FILES['image'], $_POST['maxWidth'] ?? 400, $_POST['maxHeight'] ?? 400, $_POST['format'] ?? 'jpeg');
|
||||
if (isset($result['error'])) {
|
||||
echo "<p style='color:red;'>エラー: {$result['error']}</p>";
|
||||
} else {
|
||||
$base64 = base64_encode($result['data']);
|
||||
echo "<h2>変換結果:</h2>";
|
||||
echo "<img src='data:{$result['mime']};base64,{$base64}'><br>";
|
||||
echo "<a download='converted.{$result['mime']}' href='data:{$result['mime']};base64,{$base64}'>画像を保存</a>";
|
||||
}
|
||||
}
|
||||
?>
|
||||
<?php
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_FILES['image'])) {
|
||||
$result = processImage($_FILES['image'], $_POST['maxWidth'] ?? 400, $_POST['maxHeight'] ?? 400, $_POST['format'] ?? 'jpeg');
|
||||
if (isset($result['error'])) {
|
||||
echo "<div class='alert alert-danger'>エラー: {$result['error']}</div>";
|
||||
} else {
|
||||
$base64 = base64_encode($result['data']);
|
||||
echo "<h2 class='mt-4'>変換結果:</h2>";
|
||||
echo "<img src='data:{$result['mime']};base64,{$base64}' class='img-fluid mb-3' alt='変換画像'>";
|
||||
echo "<div><a download='converted.{$result['mime']}' class='btn btn-success' href='data:{$result['mime']};base64,{$base64}'>画像を保存</a></div>";
|
||||
}
|
||||
}
|
||||
?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
</html>
|
@ -5,15 +5,12 @@ function canUseImagick(): bool {
|
||||
|
||||
function loadImage($filePath): array {
|
||||
$mime = mime_content_type($filePath);
|
||||
|
||||
// HEIC対応(Imagick前提)
|
||||
if (strpos($mime, 'heic') !== false || strpos($mime, 'heif') !== false) {
|
||||
if (!canUseImagick()) return ['error' => 'HEIC形式にはImagickが必要です'];
|
||||
$image = new Imagick($filePath);
|
||||
return ['image' => $image];
|
||||
}
|
||||
|
||||
// 通常の画像読み込み(GD)
|
||||
$imgStr = file_get_contents($filePath);
|
||||
$gdImage = @imagecreatefromstring($imgStr);
|
||||
if (!$gdImage) return ['error' => '画像の読み込みに失敗しました'];
|
||||
@ -62,76 +59,99 @@ function resizeAndCropGD($img, $maxW, $maxH, $cropX, $cropY, $cropW, $cropH): Gd
|
||||
?>
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<html lang="ja">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>画像変換ツール</title>
|
||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet">
|
||||
</head>
|
||||
<body>
|
||||
<h1>画像変換ツール</h1>
|
||||
<form method="post" enctype="multipart/form-data">
|
||||
<label>画像を選択:</label><br>
|
||||
<input type="file" name="image" accept="image/*" required><br><br>
|
||||
<div class="container py-5">
|
||||
<div class="card shadow">
|
||||
<div class="card-body">
|
||||
<h1 class="card-title mb-4">画像変換ツール</h1>
|
||||
<form method="post" enctype="multipart/form-data">
|
||||
<div class="mb-3">
|
||||
<label class="form-label">画像を選択:</label>
|
||||
<input type="file" name="image" accept="image/*" class="form-control" required>
|
||||
</div>
|
||||
|
||||
<label>出力形式:</label>
|
||||
<select name="format">
|
||||
<option value="jpeg">JPEG</option>
|
||||
<option value="png">PNG</option>
|
||||
<option value="webp">WebP</option>
|
||||
</select><br><br>
|
||||
<div class="mb-3">
|
||||
<label class="form-label">出力形式:</label>
|
||||
<select name="format" class="form-select">
|
||||
<option value="jpeg">JPEG</option>
|
||||
<option value="png">PNG</option>
|
||||
<option value="webp">WebP</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<label>透過背景を保持(PNG/WebPのみ):</label>
|
||||
<input type="checkbox" name="transparent"><br><br>
|
||||
<div class="mb-3 form-check">
|
||||
<input type="checkbox" name="transparent" class="form-check-input" id="transparent">
|
||||
<label class="form-check-label" for="transparent">透過背景を保持(PNG/WebPのみ)</label>
|
||||
</div>
|
||||
|
||||
<label>最大サイズ(幅×高さ):</label>
|
||||
<input type="number" name="maxWidth" value="400" min="1"> ×
|
||||
<input type="number" name="maxHeight" value="400" min="1"><br><br>
|
||||
<div class="mb-3">
|
||||
<label class="form-label">最大サイズ(幅×高さ):</label>
|
||||
<div class="d-flex gap-2">
|
||||
<input type="number" name="maxWidth" value="400" min="1" class="form-control" placeholder="幅">
|
||||
<span class="align-self-center">×</span>
|
||||
<input type="number" name="maxHeight" value="400" min="1" class="form-control" placeholder="高さ">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<label>トリミング(X, Y, 幅, 高さ):</label><br>
|
||||
<input type="number" name="cropX" placeholder="X" min="0">
|
||||
<input type="number" name="cropY" placeholder="Y" min="0">
|
||||
<input type="number" name="cropW" placeholder="幅" min="1">
|
||||
<input type="number" name="cropH" placeholder="高さ" min="1"><br><br>
|
||||
<div class="mb-3">
|
||||
<label class="form-label">トリミング(X, Y, 幅, 高さ):</label>
|
||||
<div class="row g-2">
|
||||
<div class="col"><input type="number" name="cropX" placeholder="X" min="0" class="form-control"></div>
|
||||
<div class="col"><input type="number" name="cropY" placeholder="Y" min="0" class="form-control"></div>
|
||||
<div class="col"><input type="number" name="cropW" placeholder="幅" min="1" class="form-control"></div>
|
||||
<div class="col"><input type="number" name="cropH" placeholder="高さ" min="1" class="form-control"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<button type="submit">変換</button>
|
||||
</form>
|
||||
<button type="submit" class="btn btn-primary">変換</button>
|
||||
</form>
|
||||
|
||||
<?php
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_FILES['image'])) {
|
||||
$tmp = $_FILES['image']['tmp_name'];
|
||||
$format = $_POST['format'] ?? 'jpeg';
|
||||
$transparent = isset($_POST['transparent']);
|
||||
$maxW = (int)($_POST['maxWidth'] ?? 400);
|
||||
$maxH = (int)($_POST['maxHeight'] ?? 400);
|
||||
$cropX = (int)($_POST['cropX'] ?? 0);
|
||||
$cropY = (int)($_POST['cropY'] ?? 0);
|
||||
$cropW = isset($_POST['cropW']) ? (int)$_POST['cropW'] : 0;
|
||||
$cropH = isset($_POST['cropH']) ? (int)$_POST['cropH'] : 0;
|
||||
<?php
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_FILES['image'])) {
|
||||
$tmp = $_FILES['image']['tmp_name'];
|
||||
$format = $_POST['format'] ?? 'jpeg';
|
||||
$transparent = isset($_POST['transparent']);
|
||||
$maxW = (int)($_POST['maxWidth'] ?? 400);
|
||||
$maxH = (int)($_POST['maxHeight'] ?? 400);
|
||||
$cropX = (int)($_POST['cropX'] ?? 0);
|
||||
$cropY = (int)($_POST['cropY'] ?? 0);
|
||||
$cropW = isset($_POST['cropW']) ? (int)$_POST['cropW'] : 0;
|
||||
$cropH = isset($_POST['cropH']) ? (int)$_POST['cropH'] : 0;
|
||||
|
||||
$result = loadImage($tmp);
|
||||
$result = loadImage($tmp);
|
||||
|
||||
if (isset($result['error'])) {
|
||||
echo "<p style='color:red;'>エラー: {$result['error']}</p>";
|
||||
} else {
|
||||
if (isset($result['gd'])) {
|
||||
$img = resizeAndCropGD($result['gd'], $maxW, $maxH, $cropX, $cropY, $cropW, $cropH);
|
||||
$out = gdToBlob($img, $format, $transparent);
|
||||
} elseif (isset($result['image'])) {
|
||||
$image = $result['image'];
|
||||
if ($cropW && $cropH) {
|
||||
$image->cropImage($cropW, $cropH, $cropX, $cropY);
|
||||
if (isset($result['error'])) {
|
||||
echo "<div class='alert alert-danger mt-4'>エラー: {$result['error']}</div>";
|
||||
} else {
|
||||
if (isset($result['gd'])) {
|
||||
$img = resizeAndCropGD($result['gd'], $maxW, $maxH, $cropX, $cropY, $cropW, $cropH);
|
||||
$out = gdToBlob($img, $format, $transparent);
|
||||
} elseif (isset($result['image'])) {
|
||||
$image = $result['image'];
|
||||
if ($cropW && $cropH) {
|
||||
$image->cropImage($cropW, $cropH, $cropX, $cropY);
|
||||
}
|
||||
$image->scaleImage($maxW, $maxH, true);
|
||||
$out = imagickToBlob($image, $format);
|
||||
}
|
||||
|
||||
$base64 = base64_encode($out['data']);
|
||||
$mime = $out['mime'];
|
||||
|
||||
echo "<h2 class='mt-4'>変換結果:</h2>";
|
||||
echo "<img src='data:$mime;base64,$base64' class='img-fluid mb-3' alt='変換画像'>";
|
||||
echo "<div><a download='converted.$format' class='btn btn-success' href='data:$mime;base64,$base64'>画像を保存</a></div>";
|
||||
}
|
||||
}
|
||||
$image->scaleImage($maxW, $maxH, true);
|
||||
$out = imagickToBlob($image, $format);
|
||||
}
|
||||
|
||||
$base64 = base64_encode($out['data']);
|
||||
$mime = $out['mime'];
|
||||
echo "<h2>変換結果:</h2>";
|
||||
echo "<img src='data:$mime;base64,$base64'><br><br>";
|
||||
echo "<a download='converted.$format' href='data:$mime;base64,$base64'>画像を保存</a>";
|
||||
}
|
||||
}
|
||||
?>
|
||||
?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
Loading…
x
Reference in New Issue
Block a user