jQuery 画像アップロードと切り取り

元記事はこちら

By klagoggle.myopenid.com

アップロードと切り取りのできるいいスクリプトを探していたら、良いのを見つけました。
http://www.webmotionuk.co.uk/php-jquery-image-upload-and-crop/
そこでCake用を作成してみました。お役に立てれば嬉しいです。では、いってみましょう!


必要なもの

導入

まず、「JqImgcrop」というコンポーネントを作成します。
「yourapp/controllers/components/」以下に「jq_imgcrop.php」というファイルを以下の内容で作成します。

Component Class:

<?php
class JqImgcropComponent extends Object {
    function uploadImage($uploadedInfo, $uploadTo, $prefix){
        $webpath = $uploadTo;
        $upload_dir = WWW_ROOT.str_replace("/", DS, $uploadTo);
        $upload_path = $upload_dir.DS;
        $max_file = "34457280";
        $max_width = 800;

        $userfile_name = $uploadedInfo['name'];
        $userfile_tmp =  $uploadedInfo["tmp_name"];
        $userfile_size = $uploadedInfo["size"];
        $filename = $prefix.basename($uploadedInfo["name"]);
        $file_ext = substr($filename, strrpos($filename, ".") + 1);
        $uploadTarget = $upload_path.$filename;

        if(empty($uploadedInfo)) {
            return false;
        }

        if (isset($uploadedInfo['name'])){
            move_uploaded_file($userfile_tmp, $uploadTarget );
            chmod ($uploadTarget , 0777);
            $width = $this->getWidth($uploadTarget);
            $height = $this->getHeight($uploadTarget);
            // Scale the image if it is greater than the width set above
            if ($width > $max_width){
                $scale = $max_width/$width;
                $uploaded = $this->resizeImage($uploadTarget,$width,$height,$scale);
            }else{
                $scale = 1;
                $uploaded = $this->resizeImage($uploadTarget,$width,$height,$scale);
            }
        }
    return array('imagePath' => $webpath.$filename, 'imageName' => $filename, 'imageWidth' => $this->getWidth($uploadTarget), 'imageHeight' => $this->getHeight($uploadTarget));
    }

    function getHeight($image) {
        $sizes = getimagesize($image);
        $height = $sizes[1];
        return $height;
    }

    function getWidth($image) {
        $sizes = getimagesize($image);
        $width = $sizes[0];
        return $width;
    }

    function resizeImage($image,$width,$height,$scale) {
        $newImageWidth = ceil($width * $scale);
        $newImageHeight = ceil($height * $scale);
        $newImage = imagecreatetruecolor($newImageWidth,$newImageHeight);
        $ext = strtolower(substr(basename($image), strrpos(basename($image), ".") + 1));
        $source = "";
        if($ext == "png"){
            $source = imagecreatefrompng($image);
        }elseif($ext == "jpg" || $ext == "jpeg"){
            $source = imagecreatefromjpeg($image);
        }elseif($ext == "gif"){
            $source = imagecreatefromgif($image);
        }
        imagecopyresampled($newImage,$source,0,0,0,0,$newImageWidth,$newImageHeight,$width,$height);
        if($ext == "png" || $ext == "PNG"){
            imagepng($newImage,$image,0);
        }elseif($ext == "jpg" || $ext == "jpeg" || $ext == "JPG" || $ext == "JPEG"){
            imagejpeg($newImage,$image,90);
        }elseif($ext == "gif" || $ext == "GIF"){
            imagegif($newImage,$image);
        }
        chmod($image, 0777);
        return $image;
    }

     function resizeThumbnailImage($thumb_image_name, $image, $width, $height, $start_width, $start_height, $scale){
        $newImageWidth = ceil($width * $scale);
        $newImageHeight = ceil($height * $scale);
        $newImage = imagecreatetruecolor($newImageWidth,$newImageHeight);
        $ext = strtolower(substr(basename($image), strrpos(basename($image), ".") + 1));
        $source = "";
        if($ext == "png"){
            $source = imagecreatefrompng($image);
        }elseif($ext == "jpg" || $ext == "jpeg"){
            $source = imagecreatefromjpeg($image);
        }elseif($ext == "gif"){
            $source = imagecreatefromgif($image);
        }
        imagecopyresampled($newImage,$source,0,0,$start_width,$start_height,$newImageWidth,$newImageHeight,$width,$height);

        if($ext == "png" || $ext == "PNG"){
            imagepng($newImage,$thumb_image_name,0);
        }elseif($ext == "jpg" || $ext == "jpeg" || $ext == "JPG" || $ext == "JPEG"){
            imagejpeg($newImage,$thumb_image_name,90);
        }elseif($ext == "gif" || $ext == "GIF"){
            imagegif($newImage,$thumb_image_name);
        }

        chmod($thumb_image_name, 0777);
        return $thumb_image_name;
    }

    function cropImage($thumb_width, $x1, $y1, $x2, $y2, $w, $h, $thumbLocation, $imageLocation){
        $scale = $thumb_width/$w;
        $cropped = $this->resizeThumbnailImage(WWW_ROOT.str_replace("/", DS,$thumbLocation),WWW_ROOT.str_replace("/", DS,$imageLocation),$w,$h,$x1,$y1,$scale);
        return $cropped;
    }
}
?>
「yourapp/views/helpers/」以下に「cropimage.php」というファイルを以下の内容で作成します。

Helper Class:

<?php
class CropimageHelper extends Helper {
    var $helpers = array('Html', 'Javascript', 'Form');

    function createJavaScript($imgW, $imgH, $thumbW, $thumbH) {
        return $this->output("<script type=\"text/javascript\">
            function preview(img, selection) {
                var scaleX = $thumbW / selection.width;
                var scaleY = $thumbH / selection.height;
                $('#thumbnail + div > img').css({
                    width: Math.round(scaleX * $imgW) + 'px',
                    height: Math.round(scaleY * $imgH) + 'px',
                    marginLeft: '-' + Math.round(scaleX * selection.x1) + 'px',
                    marginTop: '-' + Math.round(scaleY * selection.y1) + 'px'
                });
                $('#x1').val(selection.x1);
                $('#y1').val(selection.y1);
                $('#x2').val(selection.x2);
                $('#y2').val(selection.y2);
                $('#w').val(selection.width);
                $('#h').val(selection.height);
            }

            $(document).ready(function () {
                $('#save_thumb').click(function() {
                    var x1 = $('#x1').val();
                    var y1 = $('#y1').val();
                    var x2 = $('#x2').val();
                    var y2 = $('#y2').val();
                    var w = $('#w').val();
                    var h = $('#h').val();
                    if(x1==\"\" || y1==\"\" || x2==\"\" || y2==\"\"|| w==\"\" || h==\"\"){
                        alert('切り取り範囲を選択してください。');
                        return false;
                    }else{
                        return true;
                    }
                });
            });
            $(window).load(function () {
                $('#thumbnail').imgAreaSelect({ aspectRatio: '1:1', onSelectChange: preview });
            });
            </script>");
        }

    function createForm($imagePath, $tH, $tW){
        $x1 =         $this->Form->hidden('x1', array("value" => "", "id"=>"x1"));
        $y1 =         $this->Form->hidden('y1', array("value" => "", "id"=>"y1"));
        $x2 =         $this->Form->hidden('x2', array("value" => "", "id"=>"x2",));
        $y2 =         $this->Form->hidden('y2', array("value" => "", "id"=>"y2"));
        $w =             $this->Form->hidden('w', array("value" => "", "id"=>"w"));
        $h =             $this->Form->hidden('h', array("value" => "", "id"=>"h"));
        $imgP =      $this->Form->hidden('imagePath', array("value" => $imagePath));
        $imgTum = $this->Html->image($imagePath, array('style'=>'float: left; margin-right: 10px;', 'id'=>'thumbnail', 'alt'=>'Create Thumbnail'));
        $imgTumPrev = $this->Html->image($imagePath, array('style'=>'position: relative;', 'id'=>'thumbnail', 'alt'=>'Thumbnail Preview'));
        return $this->output("$imgTum
            <div style=\"position:relative; overflow:hidden; width:".$tW."px; height:".$tH."px;\">
                $imgTumPrev
            </div>
            <br style=\"clear:both;\"/>$x1 $y1 $x2 $y2 $w $h $imgP");
    }
}
?>

これで完成です。使い方を説明しましょう。

使い方

コンポーネントとヘルパーを使用するコントローラに追加します。

    var $helpers = array(..., 'Cropimage')
    var $components = array(..., 'JqImgcrop');

ではフォームを作成しましょう。以下に例を示します。

<?php
    echo $form->create('YourModel', array('action' => 'createimage_step2', "enctype" => "multipart/form-data"));?>
<?php
    echo $form->input('name');
    echo $form->input('image',array("type" => "file"));
    echo $form->end('アップロード');
?>

createimage_step2のアクション内に、コンポーネントのアップロード関数を追加します。

    $uploaded = $this->JqImgcrop->uploadImage($this->data['YourModel']['image'], '/img/upload/', 
'prefix_');

ビューにセットします。

    $this->set('uploaded',$uploaded);

コントローラは以下のようになります。

    function createimage_step2(){
        if (!empty($this->data)) {
            $uploaded = $this->JqImgcrop->uploadImage($this->data['YourModel']['image'], '/img/upload/', 'prefix_');
            $this->set('uploaded',$uploaded);
        }

2つのJavasctiptライブラリをビュー(上記の例では「createimage_step2.ctp」)に追加します。

<?php
    if(isset($javascript)):
        echo $javascript->link('jquery-1.2.6.min.js');
        echo $javascript->link('jquery.imgareaselect-0.4.2.min.js');
    endif;
?>

cropimageヘルパーを使用してフォームを作成し、Javascriptを追記します

    echo $cropimage->createJavaScript($uploaded['imageWidth'],$uploaded['imageHeight'],151,151);
    echo $cropimage->createForm($uploaded["imagePath"], $width, $height);

幅と高さの2つのパラメータで作成されるサムネイルのサイズを指定します。

IDを「save_thumb」として、「form->submit」を作成します。

    echo $form->submit('Done', array("id"=>"save_thumb"));

全体は以下のようになります。

<?php
echo $form->create('YourModel', array('action' => 'createimage_step3',"enctype" => "multipart/form-data"));
echo $form->input('id');
echo $form->hidden('name');
echo $cropimage->createForm($uploaded["imagePath"], 151, 151);
echo $form->submit('Done', array("id"=>"save_thumb"));
echo $form->end();
?>
最後に

画像の切り取りと保存のために、「createimage_step3」というアクションをコントローラに追記します。

<?php
$this->JqImgcrop->cropImage(151, $this->data['YourModel']['x1'], $this->data['YourModel']['y1'], $this->data['YourModel']['x2'], $this->data['YourModel']['y2'], $this->data['YourModel']['w'], $this->data['YourModel']['h'], $this->data['YourModel']['imagePath'], $this->data['YourModel']['imagePath'])
?>

以下のパラメータを使用します。

$thumb_width, $x1, $y1, $x2, $y2, $w, $h, $thumbLocation, $imageLocation

$thumb_width は、サムネイルの幅を指定します。
$x1, $y1, $x2, $y2, $w, $h は切り取りパラメータを指定します。
$thumbLocation は、サムネイルの保存先を指定します。
$imageLocation tは、元画像の参照先を指定します。

この関数は生成されたサムネイルのファイル名を返します。

以上です。

http://www.webmotionuk.co.uk の素晴らしい記事に感謝します!

(翻訳終わり)

訳者より

ビュー中のコーディング例ですが、上記はCakePHP 1.2系の記法です。CakePHP 1.3系では以下のようになります。

<?php
    echo $this->Form->create('YourModel', array('action' => 'createimage_step2', "enctype" => "multipart/form-data"));?>
<?php
    echo $this->Form->input('name');
    echo $this->Form->input('image',array("type" => "file"));
    echo $this->Form->end('アップロード');
?>
<?php
    if(isset($this->Javascript)):
        echo $this->Javascript->link('jquery-1.2.6.min.js');
        echo $this->Javascript->link('jquery.imgareaselect-0.4.2.min.js');
    endif;
?>
    echo $this->Cropimage->createJavaScript($uploaded['imageWidth'],$uploaded['imageHeight'],151,151);
    echo $this->Cropimage->createForm($uploaded["imagePath"], $width, $height);
    echo $this->Form->submit('Done', array("id"=>"save_thumb"));
echo $this->>Form->create('YourModel', array('action' => 'createimage_step3',"enctype" => "multipart/form-data"));
echo $this->>Form->input('id');
echo $this->>Form->hidden('name');
echo $this->>Cropimage->createForm($uploaded["imagePath"], 151, 151);
echo $this->>Form->submit('Done', array("id"=>"save_thumb"));
echo $this->>Form->end();

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です