Từ bạn quesion, có vẻ như bạn là người mới đối với GD, tôi sẽ chia sẻ một số kinh nghiệm của tôi, có thể điều này hơi lạc đề, nhưng tôi nghĩ nó sẽ hữu ích cho một người mới làm quen với GD như bạn:
Bước 1, xác thực tệp. Sử dụng chức năng sau để kiểm tra xem $_FILES['image']['tmp_name']
tệp có phải là tệp hợp lệ không:
function getContentsFromImage($image) {
if (@is_file($image) == true) {
return file_get_contents($image);
} else {
throw new \Exception('Invalid image');
}
}
$contents = getContentsFromImage($_FILES['image']['tmp_name']);
Bước 2, lấy định dạng tệp Hãy thử chức năng sau với phần mở rộng finfo để kiểm tra định dạng tệp (nội dung) của tệp. Bạn sẽ nói tại sao bạn không chỉ sử dụng $_FILES["image"]["type"]
để kiểm tra định dạng tệp? Bởi vì nó CHỈ kiểm tra phần mở rộng tệp chứ không phải nội dung tệp, nếu ai đó đổi tên tệp ban đầu được gọi là world.png thành world.jpg , $_FILES["image"]["type"]
sẽ trả về jpeg không phải png, do đó $_FILES["image"]["type"]
có thể trả về kết quả sai.
function getFormatFromContents($contents) {
$finfo = new \finfo();
$mimetype = $finfo->buffer($contents, FILEINFO_MIME_TYPE);
switch ($mimetype) {
case 'image/jpeg':
return 'jpeg';
break;
case 'image/png':
return 'png';
break;
case 'image/gif':
return 'gif';
break;
default:
throw new \Exception('Unknown or unsupported image format');
}
}
$format = getFormatFromContents($contents);
Bước 3, Nhận tài nguyên GD Lấy tài nguyên GD từ nội dung chúng ta có trước đây:
function getGDResourceFromContents($contents) {
$resource = @imagecreatefromstring($contents);
if ($resource == false) {
throw new \Exception('Cannot process image');
}
return $resource;
}
$resource = getGDResourceFromContents($contents);
Bước 4, lấy kích thước hình ảnh Bây giờ bạn có thể lấy kích thước hình ảnh với mã đơn giản sau:
$width = imagesx($resource);
$height = imagesy($resource);
Bây giờ, hãy xem chúng ta đã nhận được biến nào từ hình ảnh ban đầu:
$contents, $format, $resource, $width, $height
OK, lets move on
Bước 5, tính toán các đối số hình ảnh đã thay đổi kích thước Bước này liên quan đến câu hỏi của bạn, mục đích của hàm sau là lấy các đối số thay đổi kích thước cho hàm GD imagecopyresampled()
, mã hơi dài, nhưng nó hoạt động tốt, thậm chí nó có ba tùy chọn: kéo dài, thu nhỏ và điền vào.
căng : kích thước của hình ảnh đầu ra giống với kích thước mới mà bạn đã đặt. Sẽ không giữ tỷ lệ chiều cao / chiều rộng.
thu nhỏ : kích thước của hình ảnh đầu ra sẽ không vượt quá kích thước mới mà bạn cung cấp và giữ nguyên tỷ lệ chiều cao / chiều rộng của hình ảnh.
fill : kích thước của hình ảnh đầu ra sẽ giống với kích thước mới mà bạn cung cấp, nó sẽ cắt và thay đổi kích thước hình ảnh nếu cần và giữ nguyên tỷ lệ chiều cao / chiều rộng của hình ảnh. Tùy chọn này là những gì bạn cần trong câu hỏi của mình.
function getResizeArgs($width, $height, $newwidth, $newheight, $option) {
if ($option === 'stretch') {
if ($width === $newwidth && $height === $newheight) {
return false;
}
$dst_w = $newwidth;
$dst_h = $newheight;
$src_w = $width;
$src_h = $height;
$src_x = 0;
$src_y = 0;
} else if ($option === 'shrink') {
if ($width <= $newwidth && $height <= $newheight) {
return false;
} else if ($width / $height >= $newwidth / $newheight) {
$dst_w = $newwidth;
$dst_h = (int) round(($newwidth * $height) / $width);
} else {
$dst_w = (int) round(($newheight * $width) / $height);
$dst_h = $newheight;
}
$src_x = 0;
$src_y = 0;
$src_w = $width;
$src_h = $height;
} else if ($option === 'fill') {
if ($width === $newwidth && $height === $newheight) {
return false;
}
if ($width / $height >= $newwidth / $newheight) {
$src_w = (int) round(($newwidth * $height) / $newheight);
$src_h = $height;
$src_x = (int) round(($width - $src_w) / 2);
$src_y = 0;
} else {
$src_w = $width;
$src_h = (int) round(($width * $newheight) / $newwidth);
$src_x = 0;
$src_y = (int) round(($height - $src_h) / 2);
}
$dst_w = $newwidth;
$dst_h = $newheight;
}
if ($src_w < 1 || $src_h < 1) {
throw new \Exception('Image width or height is too small');
}
return array(
'dst_x' => 0,
'dst_y' => 0,
'src_x' => $src_x,
'src_y' => $src_y,
'dst_w' => $dst_w,
'dst_h' => $dst_h,
'src_w' => $src_w,
'src_h' => $src_h
);
}
$args = getResizeArgs($width, $height, 150, 170, 'fill');
Bước 6, chỉnh sửa ảnh sử dụng $args
, $width
, $height
, $format
và $ tài nguyên, chúng tôi nhận được từ trên vào các chức năng sau đây và nhận được tài nguyên mới của hình ảnh thay đổi kích cỡ:
function runResize($width, $height, $format, $resource, $args) {
if ($args === false) {
return;
}
$newimage = imagecreatetruecolor($args['dst_w'], $args['dst_h']);
if ($format === 'png') {
imagealphablending($newimage, false);
imagesavealpha($newimage, true);
$transparentindex = imagecolorallocatealpha($newimage, 255, 255, 255, 127);
imagefill($newimage, 0, 0, $transparentindex);
} else if ($format === 'gif') {
$transparentindex = imagecolorallocatealpha($newimage, 255, 255, 255, 127);
imagefill($newimage, 0, 0, $transparentindex);
imagecolortransparent($newimage, $transparentindex);
}
imagecopyresampled($newimage, $resource, $args['dst_x'], $args['dst_y'], $args['src_x'], $args['src_y'], $args['dst_w'], $args['dst_h'], $args['src_w'], $args['src_h']);
imagedestroy($resource);
return $newimage;
}
$newresource = runResize($width, $height, $format, $resource, $args);
Bước 7, tải nội dung mới , Sử dụng chức năng sau để lấy nội dung từ tài nguyên GD mới:
function getContentsFromGDResource($resource, $format) {
ob_start();
switch ($format) {
case 'gif':
imagegif($resource);
break;
case 'jpeg':
imagejpeg($resource, NULL, 100);
break;
case 'png':
imagepng($resource, NULL, 9);
}
$contents = ob_get_contents();
ob_end_clean();
return $contents;
}
$newcontents = getContentsFromGDResource($newresource, $format);
Bước 8 lấy phần mở rộng , Sử dụng chức năng sau để nhận phần mở rộng từ định dạng hình ảnh (lưu ý, định dạng hình ảnh không bằng phần mở rộng hình ảnh):
function getExtensionFromFormat($format) {
switch ($format) {
case 'gif':
return 'gif';
break;
case 'jpeg':
return 'jpg';
break;
case 'png':
return 'png';
}
}
$extension = getExtensionFromFormat($format);
Bước 9 lưu hình ảnh Nếu chúng ta có một người dùng tên là mike, bạn có thể làm như sau, nó sẽ lưu vào cùng một thư mục với tập lệnh php này:
$user_name = 'mike';
$filename = $user_name . '.' . $extension;
file_put_contents($filename, $newcontents);
Bước 10 phá hủy tài nguyên Đừng quên phá hủy tài nguyên GD!
imagedestroy($newresource);
hoặc bạn có thể viết tất cả mã của mình vào một lớp và chỉ cần sử dụng như sau:
public function __destruct() {
@imagedestroy($this->resource);
}
LỜI KHUYÊN
Tôi khuyên bạn không nên chuyển đổi định dạng tệp mà người dùng tải lên, bạn sẽ gặp nhiều vấn đề.