目次
ディスカッション (解決策) に返信します
ホームページ バックエンド開発 PHPチュートリアル PHP のトリミングの問題についてアドバイスをお願いします。私は 1 日かけて取り組んできました。

PHP のトリミングの問題についてアドバイスをお願いします。私は 1 日かけて取り組んできました。

Jun 23, 2016 pm 01:33 PM

JCROP を使用してフロントエンドの x、y 座標、幅、高さを取得し、それらを処理のために uphoto.php に渡します。これですべてが正常になりますが、フロントエンド ユーザーが選択した画像の幅は異なります。サイズが大きすぎます(CSSスタイルを使用して、ユーザーが選択した画像の最大幅を制御します)680px)、トリミングされた画像は異常です...いくつかの情報を確認したところ、比例して変換する必要があると記載されていましたが、どの程度でしょうか?ユーザーが選択した画像の幅(680pxを超える場合)は680に変換されますか?

これは uphoto.php です:

$x1 = $_POST["x1"];$x2 = $_POST["x2"];$y1 = $_POST["y1"];$y2 = $_POST["y2"];$targ_w = $_POST["w"];$targ_h = $_POST["h"];if ($_FILES["mfile"]["error"]){echo "error: " . $_FILES["file"]["error"];}if (!empty($_FILES["mfile"]["name"])){ //提取文件域内容名称,并判断$path = "/upload/user/photo/"; //上传路径//检查是否有该文件夹,如果没有就创建,并给予最高权限//if(!file_exists($path)){mkdir("$path", 0700);}//允许上传的文件格式$allow_type = array("image/gif","image/pjpeg","image/jpeg","image/png");//检查上传文件是否在允许上传的类型if(!in_array($_FILES["mfile"]["type"], $allow_type)){echo "error:格式有误,仅支持gif/jpg/png"; exit();}//检测图片大小if($_FILES["mfile"]["size"] > 5*1024*1024){echo "error:文件不得超过5M"; exit();}$filetype = $_FILES["mfile"]["type"];if($filetype == "image/jpeg"){$img_type = ".jpg";}if ($filetype == "image/jpg") {$img_type = ".jpg";}if ($filetype == "image/pjpeg") {$img_type = ".jpg";}if($filetype == "image/gif"){$img_type = ".gif";}if($filetype == "image/png"){$img_type = ".png";}if($_FILES["mfile"]["name"]){$randstr = random_str().date("YmdHis"); //获取时间并赋值给变量$saveto = $_SERVER['DOCUMENT_ROOT'].$path.$randstr.$img_type; //图片的完整路径$newimg = $randstr.$img_type; //图片名称$flag=1;}//END IFif ($flag){$result = move_uploaded_file($_FILES["mfile"]["tmp_name"], $saveto);}//特别注意这里传递给move_uploaded_file的第一个参数为上传到服务器上的临时文件$src_file = $saveto;}}$type = exif_imagetype($src_file);$support_type = array(IMAGETYPE_JPEG , IMAGETYPE_PNG , IMAGETYPE_GIF);if(!in_array($type, $support_type, true)){echo "error:当前图片格式非JPG/PNG/GIF";exit();}//Load imageswitch($type) {case IMAGETYPE_JPEG :$src_img = imagecreatefromjpeg($src_file);break;case IMAGETYPE_PNG :$src_img = imagecreatefrompng($src_file);break;case IMAGETYPE_GIF :$src_img = imagecreatefromgif($src_file);break;default:echo "Load image error!";exit();}$dst_r = ImageCreateTrueColor($targ_w, $targ_h);list($width_orig, $height_orig) = getimagesize($src_file);//if ($width_orig > 680){//$new_width_orig = 680;//$new_height_orig = ($height_orig*680)/$width_orig;//}//else {//$new_width_orig = $targ_w;//$new_height_orig = $targ_h;//}//echo $new_width_orig."<br />";//echo $new_height_orig."<br />";//echo "x:".$x1."<br />";//echo "y:".$y1;//exit();imagecopyresampled($dst_r, $src_img, 0, 0, $x1, $y1, $targ_w, $targ_h, $targ_w, $targ_h);//imagecopyresampled($dst_r, $src_img, 0, 0, $x1, $y1, $targ_w, $targ_h, $targ_w, $targ_h);switch($type) {case IMAGETYPE_JPEG :header('Content-type: image/jpeg');imagejpeg($dst_r, null, 100);break;case IMAGETYPE_PNG :header('Content-type: image/png');imagepng($dst_r, null, 100);break;case IMAGETYPE_GIF :header('Content-type: image/gif');imagegif($dst_r, null, 100);break;default:break;}echo "<img src='". $dst_r ."' />";exit;
ログイン後にコピー


アドバイスをください


ディスカッション (解決策) に返信します

CSS スタイルを使用して、ユーザーが選択した画像の最大幅を 680px に制御します
これは、ユーザーに表示されるのは、動的に拡大縮小されたコピーであることを意味します
次に、トリミング領域の座標を渡すときに、画像の元のサイズも渡す必要があります
それを変換するだけです
画像の最大幅は 680px です
ということですユーザーには動的に拡大縮小されたコピーが表示されます
次に、トリミング領域の座標を渡すときに、画像の元のサイズも渡す必要があります

それを変換するだけです

X= x/680*画像の幅



ありがとうございます、あなたのように変換した後でも、それはまだ正常ではありません..

list($width_orig, $height_orig) = getimagesize($src_file);

if ($width_orig > 680){
$nx = $x1 /680* $ width_orig
}
else {
$ nx = $ x1
}








_w, $ targ_h) ;



y 方向は計算されません

list($width_orig, $height_orig) = getimagesize($src_file)
if ($width_orig > 680){
$nx = $x1/680 * $wi dth_orig ;
$new_height = $height_orig*680/$width_orig;
$y1/$new_height * $height_orig;
else {
$nx = $x1;
imagecopyres; ( $dst_r, $src_img, 0, 0, $nx, $ny, $targ_w, $targ_h, $targ_w, $targ_h);

このような計算はまだ機能しません...

$targ_w, $targ_hこの2つ 切断幅と高さ この2つが関係しているのでしょうか?


以前書いたトリミングを参照してください。トリミングしたいので、幅と高さの一方がトリミングされたサイズの幅と高さと同じになり、もう一方の側がトリミングされます。
http://blog.csdn.net/fdipzone/article/details/9316385

    /** 获取目标图生成的size     * @return Array $width, $height     */      private function get_size(){          list($owidth, $oheight) = getimagesize($this->_source);          $width = (int)($this->_width);          $height = (int)($this->_height);                    switch($this->_type){              case 'fit':                  $pic_w = $width;                  $pic_h = (int)($pic_w*$oheight/$owidth);                  if($pic_h>$height){                      $pic_h = $height;                      $pic_w = (int)($pic_h*$owidth/$oheight);                  }                  break;              case 'crop':                  $pic_w = $width;                  $pic_h = (int)($pic_w*$oheight/$owidth);                  if($pic_h<$height){                      $pic_h = $height;                      $pic_w = (int)($pic_h*$owidth/$oheight);                  }                  break;          }            return array($pic_w, $pic_h);      } 
ログイン後にコピー
ログイン後にコピー


以前書いたトリミングを参照してください。トリミングしたいので、幅と高さの一方がトリミングされたサイズの幅と高さと同じになり、もう一方の側がトリミングされます。
http://blog.csdn.net/fdipzone/article/details/9316385

    /** 获取目标图生成的size     * @return Array $width, $height     */      private function get_size(){          list($owidth, $oheight) = getimagesize($this->_source);          $width = (int)($this->_width);          $height = (int)($this->_height);                    switch($this->_type){              case 'fit':                  $pic_w = $width;                  $pic_h = (int)($pic_w*$oheight/$owidth);                  if($pic_h>$height){                      $pic_h = $height;                      $pic_w = (int)($pic_h*$owidth/$oheight);                  }                  break;              case 'crop':                  $pic_w = $width;                  $pic_h = (int)($pic_w*$oheight/$owidth);                  if($pic_h<$height){                      $pic_h = $height;                      $pic_w = (int)($pic_h*$owidth/$oheight);                  }                  break;          }            return array($pic_w, $pic_h);      } 
ログイン後にコピー
ログイン後にコピー



ありがとう、私はあなたがしたように調整しましたが、まだ正常ではありません:

list($width_orig, $height_orig) = getimagesize($src_file);
$pic_w = $targ_w;
$pic_h = (int)($pic_w*$height_orig/$width_orig);
$pic_h = $targ_h;
$pic_w = (int)($pic_h*$width_orig/$height_orig);
}
imagecopyresampled($dst_r, $src_img, 0, 0, $x1, $y1, $targ_w, $targ_h, $pic_w, $pic_h ) ;

次に、幅 680 の写真を幅 680 ピクセルに切り取ってトリミングしたいと思います...

幅 680 を超える写真を幅 680 ピクセルに切り取ります
これは Picture によって取得されますwidth / 画像の高さ = 680 / h
h = 680 / 画像の幅 * 画像の高さ
$targ_h = 680 / $pic_w * $pic_h;
$targ_w = 680; より大きい幅の画像680 は 680px の幅にトリミングされます
画像の幅 / 画像の高さ = 680 / h から h = 680 / 画像の幅 * 画像の高さを取得します

つまり

$targ_h = 680 / $pic_w * $pic_h;

$targ_w = 680;

谢谢啊,我现在通过将用户选择的图片若超过680px就裁切成宽度680px(高度通过你那样的算法算的),然后再裁切成头像,测试是正常的,但还有几个细节我有点不明白,下面是源码:


$x1 = $_POST["x1"];$x2 = $_POST["x2"];$y1 = $_POST["y1"];$y2 = $_POST["y2"];$targ_w = $_POST["w"];$targ_h = $_POST["h"];if ($_FILES["mfile"]["error"]){echo "error: " . $_FILES["file"]["error"];}if (!empty($_FILES["mfile"]["name"])){ //提取文件域内容名称,并判断$path = "/upload/user/photo/"; //上传路径//检查是否有该文件夹,如果没有就创建,并给予最高权限//if(!file_exists($path)){mkdir("$path", 0700);}//允许上传的文件格式$allow_type = array("image/gif","image/pjpeg","image/jpeg","image/png");//检查上传文件是否在允许上传的类型if(!in_array($_FILES["mfile"]["type"], $allow_type)){echo "error:格式有误,仅支持gif/jpg/png"; exit();}//检测图片大小if($_FILES["mfile"]["size"] > 5*1024*1024){echo "error:文件不得超过5M"; exit();}$filetype = $_FILES["mfile"]["type"];if($filetype == "image/jpeg"){$img_type = ".jpg";}if ($filetype == "image/jpg") {$img_type = ".jpg";}if ($filetype == "image/pjpeg") {$img_type = ".jpg";}if($filetype == "image/gif"){$img_type = ".gif";}if($filetype == "image/png"){$img_type = ".png";}if($_FILES["mfile"]["name"]){$randstr = random_str().date("YmdHis"); //获取时间并赋值给变量$saveto = $_SERVER['DOCUMENT_ROOT'].$path.$randstr.$img_type; //图片的完整路径$newimg = $randstr.$img_type; //图片名称$flag=1;}//END IFif ($flag){$result = move_uploaded_file($_FILES["mfile"]["tmp_name"], $saveto);}//特别注意这里传递给move_uploaded_file的第一个参数为上传到服务器上的临时文件$src_file = $saveto;}}list($width_orig, $height_orig) = getimagesize($src_file);if ($width_orig > 680){$tmp_type = exif_imagetype($src_file);switch($tmp_type) {case IMAGETYPE_JPEG :$tmp_src_img = imagecreatefromjpeg($src_file);break;case IMAGETYPE_PNG :$tmp_src_img = imagecreatefrompng($src_file);break;case IMAGETYPE_GIF :$tmp_src_img = imagecreatefromgif($src_file);break;default:echo "Load image error!";exit();}$ntmp_width = 680;$ntmp_height = $height_orig*$ntmp_width/$width_orig;$ntmp_imgr = ImageCreateTrueColor($ntmp_width, $ntmp_height);imagecopyresampled($ntmp_imgr, $tmp_src_img, 0, 0, 0, 0, $ntmp_width, $ntmp_height, $width_orig, $height_orig);switch($tmp_type) {case IMAGETYPE_JPEG :header('Content-type: image/jpeg');imagejpeg($ntmp_imgr, $_SERVER['DOCUMENT_ROOT'].$path.$randstr.$img_type, 100);break;case IMAGETYPE_PNG :header('Content-type: image/png');imagepng($ntmp_imgr, $_SERVER['DOCUMENT_ROOT'].$path.$randstr.$img_type, 100);break;case IMAGETYPE_GIF :header('Content-type: image/gif');imagegif($ntmp_imgr, $_SERVER['DOCUMENT_ROOT'].$path.$randstr.$img_type, 100);break;default:break;}$src_file = $_SERVER['DOCUMENT_ROOT'].$path.$randstr.$img_type;}$type = exif_imagetype($src_file);switch($type) {case IMAGETYPE_JPEG :$src_img = imagecreatefromjpeg($src_file);break;case IMAGETYPE_PNG :$src_img = imagecreatefrompng($src_file);break;case IMAGETYPE_GIF :$src_img = imagecreatefromgif($src_file);break;default:echo "Load image error!";exit();}$dst_r = ImageCreateTrueColor($targ_w, $targ_h);imagecopyresampled($dst_r, $src_img, 0, 0, $x1, $y1, $targ_w, $targ_h, $targ_w, $targ_h);switch($type) {case IMAGETYPE_JPEG :header('Content-type: image/jpeg');imagejpeg($dst_r, null, 100);break;case IMAGETYPE_PNG :header('Content-type: image/png');imagepng($dst_r, null, 100);break;case IMAGETYPE_GIF :header('Content-type: image/gif');imagegif($dst_r, null, 100);break;default:break;}echo "<img src='". $dst_r ."' />";exit;
ログイン後にコピー


其中那个红色部分,我如果换成上传的图片的宽度和高度($width_orig,$height_orig),就会不正常...
按我现在这样的方式,有没办法优化下?
我看好多使用裁切之后 都会 imagedestory() 这个是删除图片流,而不是原图吧?

图片的宽、高 应通过 imagesx($src_img)、imagesy($src_img) 取得,传入的可能不正确
 imagedestory() 是释放资源,比如  imagedestory($src_img)
不写也可以,php 会替你释放的
 

图片的宽、高 应通过 imagesx($src_img)、imagesy($src_img) 取得,传入的可能不正确
 imagedestory() 是释放资源,比如  imagedestory($src_img)
不写也可以,php 会替你释放的
 



谢谢啊 我现在想把裁切好的图片保存到数据库中,却出现 图像 ... 因存在错误而无法显示。

这是代码:

$dst_r = ImageCreateTrueColor($targ_w, $targ_h);
imagecopyresampled($dst_r, $src_img, 0, 0, $x1, $y1, $targ_w, $targ_h, $targ_w, $targ_h);

$mphoto = $path.$uid.$randstr.$img_type;
$mphoto_save = $_SERVER['DOCUMENT_ROOT'].$mphoto;
//echo $mphoto_save;
//exit();
switch($type) {
case IMAGETYPE_JPEG :
header('Content-type: image/jpeg');
imagejpeg($dst_r, $mphoto_save, 100);
break;
case IMAGETYPE_PNG :
header('Content-type: image/png');
imagepng($dst_r, $mphoto_save, 100);
break;
case IMAGETYPE_GIF :
header('Content-type: image/gif');
imagegif($dst_r, $mphoto_save, 100);
break;
default:
break;
}

//echo "";
//exit();

imagedestory($dst_r); 
imagedestory($src_img);



if (!mysqli_query($conn, "update dh_member set photo='". $mphoto ."' where id=". $uid ."")){die(mysqli_error($conn));}
echo "
<script>document.back_form.submit();</script>";
exit();

是怎么回事啊,我都没有输出图片啊..

假定 $dst_r 是 image 资源
imagegif($dst_r); 就是输出图片数据流
imagegif($dst_r, '图片文件名'); 就是保存到文件

数据库保存图片文件名即可
如果数据库要保存图片数据,则应用合适的 blob 类型字段 
数据从 图片文件 读取或拦截php的输出
用 bin2hex 函数转换成字符串,在前面加 ‘0x'

假定 $dst_r 是 image 资源
imagegif($dst_r); 就是输出图片数据流
imagegif($dst_r, '图片文件名'); 就是保存到文件

数据库保存图片文件名即可
如果数据库要保存图片数据,则应用合适的 blob 类型字段 
数据从 图片文件 读取或拦截php的输出
用 bin2hex 函数转换成字符串,在前面加 ‘0x'



谢谢啊,怎么做到让它不输出图片流呢(输出图片流为的就是保存成新文件名),直接保存到文件夹,然后更新数据库呢?
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

AI Hentai Generator

AI Hentai Generator

AIヘンタイを無料で生成します。

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

PHPロギング:PHPログ分析のベストプラクティス PHPロギング:PHPログ分析のベストプラクティス Mar 10, 2025 pm 02:32 PM

PHPロギングは、Webアプリケーションの監視とデバッグ、および重要なイベント、エラー、ランタイムの動作をキャプチャするために不可欠です。システムのパフォーマンスに関する貴重な洞察を提供し、問題の特定に役立ち、より速いトラブルシューティングをサポートします

Laravelでフラッシュセッションデータを使用します Laravelでフラッシュセッションデータを使用します Mar 12, 2025 pm 05:08 PM

Laravelは、直感的なフラッシュメソッドを使用して、一時的なセッションデータの処理を簡素化します。これは、アプリケーション内に簡単なメッセージ、アラート、または通知を表示するのに最適です。 データは、デフォルトで次の要求のためにのみ持続します。 $リクエスト -

PHPのカール:REST APIでPHPカール拡張機能を使用する方法 PHPのカール:REST APIでPHPカール拡張機能を使用する方法 Mar 14, 2025 am 11:42 AM

PHPクライアントURL(CURL)拡張機能は、開発者にとって強力なツールであり、リモートサーバーやREST APIとのシームレスな対話を可能にします。尊敬されるマルチプロトコルファイル転送ライブラリであるLibcurlを活用することにより、PHP Curlは効率的なexecuを促進します

Laravelテストでの簡略化されたHTTP応答のモッキング Laravelテストでの簡略化されたHTTP応答のモッキング Mar 12, 2025 pm 05:09 PM

Laravelは簡潔なHTTP応答シミュレーション構文を提供し、HTTP相互作用テストを簡素化します。このアプローチは、テストシミュレーションをより直感的にしながら、コード冗長性を大幅に削減します。 基本的な実装は、さまざまな応答タイプのショートカットを提供します。 Illuminate \ support \ facades \ httpを使用します。 http :: fake([[ 'google.com' => 'hello world'、 'github.com' => ['foo' => 'bar']、 'forge.laravel.com' =>

Codecanyonで12の最高のPHPチャットスクリプト Codecanyonで12の最高のPHPチャットスクリプト Mar 13, 2025 pm 12:08 PM

顧客の最も差し迫った問題にリアルタイムでインスタントソリューションを提供したいですか? ライブチャットを使用すると、顧客とのリアルタイムな会話を行い、すぐに問題を解決できます。それはあなたがあなたのカスタムにより速いサービスを提供することを可能にします

PHPにおける後期静的結合の概念を説明します。 PHPにおける後期静的結合の概念を説明します。 Mar 21, 2025 pm 01:33 PM

記事では、PHP 5.3で導入されたPHPの後期静的結合(LSB)について説明し、より柔軟な継承を求める静的メソッドコールのランタイム解像度を可能にします。 LSBの実用的なアプリケーションと潜在的なパフォーマ

フレームワークのカスタマイズ/拡張:カスタム機能を追加する方法。 フレームワークのカスタマイズ/拡張:カスタム機能を追加する方法。 Mar 28, 2025 pm 05:12 PM

この記事では、フレームワークにカスタム機能を追加し、アーキテクチャの理解、拡張ポイントの識別、統合とデバッグのベストプラクティスに焦点を当てています。

See all articles