Please enable JavaScript!
Bitte aktiviere JavaScript!
S'il vous plaît activer JavaScript!
Por favor,activa el JavaScript!
antiblock.org

 |  |  |  | 
Anda ingin membuat website?
Untuk Anda yang sedang mencari orang untuk jasa pembuatan website, Saya akan bantu buatkan aplikasi sesuai kebutuhan Anda. Segera hubungi : [email protected] Selengkapnya tentang profil saya klik www.rizaldimaulidia.com.

JQuery PHP Tips and Trick

Cara Membuat Crop Gambar Plus Upload dengan PHP

img-responsive

Maaf baru update lagi sahabat mynotescode di karenakan kami sedang ada banyak kesibukan jadi baru bisa update lagi. Oke langsung saja kali ini kita bakalan ngebahas tentang Cara Membuat Upload Gambar Plus Crop Gambar dan seperti biasa kita bakalan membahasnya secara terperinci dan step by step agar kawan-kawan dapat memahaminya dengan mudah


DEMO
Sebelum membaca tutorialnya, mungkin ada yang mau lihat demonya terlebih dahulu. Klik link berikut untuk melihat demonya : Lihat Demo.


STEP 1 – Persiapan

  1. Download JQUERY : Klik Disini
    Bingung cara downloadnya? klik disini untuk melihat caranya.
  2. Download Bootstrap : Klik Disini
    Bingung cara downloadnya? klik disini untuk melihat caranya.
  3. Download librari JQuery Cropper : Klik Disini
    Bingung cara downloadnya? klik disini untuk melihat caranya.
  4. Buat sebuah folder baru dengan nama crop_upload, lalu simpan pada folder xampp/htdocs/.
  5. Buat sebuah folder dengan nama css, lalu simpan pada folder xampp/htdocs/crop_upload/.
  6. Buat sebuah folder dengan nama js, lalu simpan pada folder xampp/htdocs/crop_upload/
  7. Esktrak file bootstrap.7z yang telah didownload tadi.
  8. Copy and paste file bootstrap.min.css dari folder bootstrap/css/ yang telah diekstrak tadi ke folder xampp/htdocs/crop_upload/css/.
  9. Copy and paste file bootstrap.min.js dari folder bootstrap/js/ yang telah diekstrak tadi ke folder xampp/htdocs/crop_upload/js/
  10. Copy and paste file jquery.min.js yang telah didownload tadi ke folder xampp/htdocs/crop_upload/js/.
  11. Esktrak file cropper.zip yang telah didownload tadi.
  12. Copy and paste folder cropper yang telah diesktrak tadi ke folder xampp/htdocs/crop_upload/js/.

STEP 2 – Proses Crop

Sekarang tulis kode javasctript berikut untuk proses upload dan crop gambarnya. Buat sebuah file dengan nama main.js, lalu simpan pada folder xampp/htdocs/crop_upload/js/. Berikut Script javascriptnya :

(function (factory) {
  if (typeof define === 'function' && define.amd) {
    // AMD. Register as anonymous module.
    define(['jquery'], factory);
  } else if (typeof exports === 'object') {
    // Node / CommonJS
    factory(require('jquery'));
  } else {
    // Browser globals.
    factory(jQuery);
  }
})(function ($) {

  'use strict';

  var console = window.console || { log: function () {} };

  function CropAvatar($element) {
    // mengambil element 
    this.$container = $element;

    // memanggil class avatar-view
    this.$avatarView = this.$container.find('.avatar-view');
    // memanggil tag html img
    this.$avatar = this.$avatarView.find('img');
    // memanggil id avatar-modal
    this.$avatarModal = this.$container.find('#avatar-modal');
    // memanggil class loading
    this.$loading = this.$container.find('.loading');

    // memanggil class avatar-form
    this.$avatarForm = this.$avatarModal.find('.avatar-form');
    // memanggil class avatar-form
    this.$avatarUpload = this.$avatarForm.find('.avatar-upload');
    // memanggil class avatar src
    this.$avatarSrc = this.$avatarForm.find('.avatar-src');
    // memanggil class avatar-data
    this.$avatarData = this.$avatarForm.find('.avatar-data');
    // memanggil class avatar-input
    this.$avatarInput = this.$avatarForm.find('.avatar-input');
    // memanggil class avatar save
    this.$avatarSave = this.$avatarForm.find('.avatar-save');
    // memanggil class avatar btns
    this.$avatarBtns = this.$avatarForm.find('.avatar-btns');

    // memanggil avatar-wrapper
    this.$avatarWrapper = this.$avatarModal.find('.avatar-wrapper');
    // memanggil avatar-preview
    this.$avatarPreview = this.$avatarModal.find('.avatar-preview');

    // memanggil function init untuk menjalankan CropAvatar
    this.init();
  }

  CropAvatar.prototype = {
    constructor: CropAvatar,

    support: {
      fileList: !!$('<input type="file">').prop('files'),
      blobURLs: !!window.URL && URL.createObjectURL,
      formData: !!window.FormData
    },

    // function untuk memulai proses cropavatar
    init: function () {
      this.support.datauri = this.support.fileList && this.support.blobURLs;

      if (!this.support.formData) {
        this.initIframe();
      }

      this.initTooltip();
      this.initModal();
      this.addListener();
    },

    // function menambah list gambar agar dapat di munculkan juga di bagian kotak-kotak kiri di atas
    addListener: function () {
      this.$avatarView.on('click', $.proxy(this.click, this));
      this.$avatarInput.on('change', $.proxy(this.change, this));
      this.$avatarForm.on('submit', $.proxy(this.submit, this));
      this.$avatarBtns.on('click', $.proxy(this.rotate, this));
    },

    // function untuk memunculkan title pada saat kursor di dekatkan di gambar untuk menambah gambar
    initTooltip: function () {
      this.$avatarView.tooltip({
        placement: 'bottom'
      });
    },

    // function untuk menampilkan show modal cropper avatar
    initModal: function () {
      this.$avatarModal.modal({
        show: false
      });
    },

    // function untuk menampilkan gambar preview di dalam canvas
    initPreview: function () {
      var url = this.$avatar.attr('src');

      this.$avatarPreview.html('<img src="' + url + '">%MCEPASTEBIN%');
    },

    // fungsi untuk membuat frame agar gambar dapat di tampilkan pada canvas
    initIframe: function () {
      var target = 'upload-iframe-' + (new Date()).getTime();
      var $iframe = $('<iframe>').attr({
            name: target,
            src: ''
          });
      var _this = this;

      // Ready ifrmae
      $iframe.one('load', function () {

        // respond response
        $iframe.on('load', function () {
          var data;

          try {
            data = $(this).contents().find('body').text();
          } catch (e) {
            console.log(e.message);
          }

          if (data) {
            try {
              data = $.parseJSON(data);
            } catch (e) {
              console.log(e.message);
            }

            _this.submitDone(data);
          } else {
            _this.submitFail('Image upload failed!');
          }

          _this.submitEnd();

        });
      });

      this.$iframe = $iframe;
      this.$avatarForm.attr('target', target).after($iframe.hide());
    },

    // fungsi untuk memulai pertama kali pada saat di klik gambar awal
    click: function () {
      this.$avatarModal.modal('show');
      this.initPreview();
    },

    // fungsi untuk merubah ukuran gambar yang akan di crop
    change: function () {
      var files;
      var file;

      if (this.support.datauri) {
        files = this.$avatarInput.prop('files');

        if (files.length > 0) {
          file = files[0];

          if (this.isImageFile(file)) {
            if (this.url) {
              URL.revokeObjectURL(this.url); // Revoke the old one
            }

            this.url = URL.createObjectURL(file);
            this.startCropper();
          }
        }
      } else {
        file = this.$avatarInput.val();

        if (this.isImageFile(file)) {
          this.syncUpload();
        }
      }
    },

    // fungsi untuk mengirimkan gambar yang sudah di crop ke proses penyimpana gambar
    submit: function () {
      if (!this.$avatarSrc.val() && !this.$avatarInput.val()) {
        return false;
      }

      if (this.support.formData) {
        this.ajaxUpload();
        return false;
      }
    },

    // fungsi untuk rotasi gambar tersebut pada canvas
    rotate: function (e) {
      var data;

      if (this.active) {
        data = $(e.target).data();

        if (data.method) {
          this.$img.cropper(data.method, data.option);
        }
      }
    },

    // fungsi untuk meng validasi type gambar yang di upload
    isImageFile: function (file) {
      if (file.type) {
        return /^image\/\w+$/.test(file.type);
      } else {
        return /\.(jpg|jpeg|png|gif)$/.test(file);
      }
    },

    // funsgi untuk menjalankan crop gambar
    startCropper: function () {
      var _this = this;

      if (this.active) {
        this.$img.cropper('replace', this.url);
      } else {
        this.$img = $('<img src="' + this.url + '">');
        this.$avatarWrapper.empty().html(this.$img);
        this.$img.cropper({
          aspectRatio: 1,
          preview: this.$avatarPreview.selector,
          crop: function (e) {
            var json = [
                  '{"x":' + e.x,
                  '"y":' + e.y,
                  '"height":' + e.height,
                  '"width":' + e.width,
                  '"rotate":' + e.rotate + '}'
                ].join();

            _this.$avatarData.val(json);
          }
        });

        this.active = true;
      }

      this.$avatarModal.one('hidden.bs.modal', function () {
        _this.$avatarPreview.empty();
        _this.stopCropper();
      });
    },

    // fungsi untuk memberhentikan proses crop yang sedang berjalan
    stopCropper: function () {
      if (this.active) {
        this.$img.cropper('destroy');
        this.$img.remove();
        this.active = false;
      }
    },

    // fungsi untuk meng upload gambar yang tadi sudah di masukan dan di proses
    ajaxUpload: function () {
      var url = this.$avatarForm.attr('action');
      var data = new FormData(this.$avatarForm[0]);
      var _this = this;

      $.ajax(url, {
        type: 'post',
        data: data,
        dataType: 'json',
        processData: false,
        contentType: false,

        beforeSend: function () {
          _this.submitStart();
        },

        success: function (data) {
          _this.submitDone(data);
        },

        error: function (XMLHttpRequest, textStatus, errorThrown) {
          _this.submitFail(textStatus || errorThrown);
        },

        complete: function () {
          _this.submitEnd();
        }
      });
    },

    // fungsi untuk membanding kan gambar yang sebelum di crop dengan sesudah di crop
    syncUpload: function () {
      this.$avatarSave.click();
    },

    // fungsi untuk memulai crop
    submitStart: function () {
      this.$loading.fadeIn();
    },

    // fungsi untuk menyimpan hasil setelah proses simpan gambar telah selesai dan menerima response yang di terima
    submitDone: function (data) {
      console.log(data);

      if ($.isPlainObject(data) && data.state === 200) {
        if (data.result) {
          this.url = data.result;

          if (this.support.datauri || this.uploaded) {
            this.uploaded = false;
            this.cropDone();
          } else {
            this.uploaded = true;
            this.$avatarSrc.val(this.url);
            this.startCropper();
          }

          this.$avatarInput.val('');
        } else if (data.message) {
          this.alert(data.message);
        }
      } else {
        this.alert('Failed to response');
      }
    },

    // fungsi ketika proses mengalami ke gagalan akan mengeluarkan pesan error nya
    submitFail: function (msg) {
      this.alert(msg);
    },

    // fungsi untuk mengakhiri proses cropper
    submitEnd: function () {
      this.$loading.fadeOut();
    },

    // fungsi ini akan di panggil ketika proses cropper telah selesai
    cropDone: function () {
      this.$avatarForm.get(0).reset();
      this.$avatar.attr('src', this.url);
      this.stopCropper();
      this.$avatarModal.modal('hide');
    },

    // fungsi untuk menampilkan pesan error
    alert: function (msg) {
      var $alert = [
            '<div class="alert alert-danger avatar-alert alert-dismissable">',
              '<button type="button" class="close" data-dismiss="alert">&times;</button>',
              msg,
            '</div>'
          ].join('');

      this.$avatarUpload.after($alert);
    }
  };

  // untuk memulai keseluruhan coding yang sudah kita buat tadi supaya dapat berjalan
  $(function () {
    return new CropAvatar($('#crop-avatar'));
  });

});

STEP 3 – View

Buat tampilan dan IMK(Interaksi Manusia Komputer) nya untuk lebih mudah dan enak di gunakan oleh kawan-kawan semua. Buat sebuah file index.html lalu simpan pada folder xampp/htdocs/crop_upload/. Berikut tampilan yang akan kita buat :

Cropper - Cara Membuat Crop Gambar Plus Upload dengan PHP - My Notes Code

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta http-equiv="x-ua-compatible" content="ie=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
  <meta name="description" content="A complete example of Cropper.">
  <meta name="keywords" content="HTML, CSS, JS, JavaScript, jQuery plugin, image cropping, image crop, image move, image zoom, image rotate, image scale, front-end, frontend, web development">
  <meta name="author" content="Fengyuan Chen">
  <title>Cropper</title>
  <link rel="stylesheet" href="css/bootstrap.min.css">
  <link rel="stylesheet" href="js/cropper/cropper.min.css">
  <link rel="stylesheet" href="css/main.css">

  <!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
  <!--[if lt IE 9]>
    <script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
    <script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
  <![endif]-->
</head>
<body>
  <div class="container" id="crop-avatar">

    <!-- Current avatar -->
    <div class="avatar-view" title="Change the avatar">
      <img src="images/picture.jpg" alt="Avatar">
    </div>

    <!-- Cropping modal -->
    <div class="modal fade" id="avatar-modal" aria-hidden="true" aria-labelledby="avatar-modal-label" role="dialog" tabindex="-1">
      <div class="modal-dialog modal-lg">
        <div class="modal-content">
          <form class="avatar-form" action="crop.php" enctype="multipart/form-data" method="post">
            <div class="modal-header">
              <button type="button" class="close" data-dismiss="modal">&times;</button>
              <h4 class="modal-title" id="avatar-modal-label">Change Avatar</h4>
            </div>
            <div class="modal-body">
              <div class="avatar-body">

                <!-- Upload image and data -->
                <div class="avatar-upload">
                  <input type="hidden" class="avatar-src" name="avatar_src">
                  <input type="hidden" class="avatar-data" name="avatar_data">
                  <label for="avatarInput">Local upload</label>
                  <input type="file" class="avatar-input" id="avatarInput" name="avatar_file">
                </div>

                <!-- Crop and preview -->
                <div class="row">
                  <div class="col-md-9">
                    <div class="avatar-wrapper"></div>
                  </div>
                  <div class="col-md-3">
                    <div class="avatar-preview preview-lg"></div>
                    <div class="avatar-preview preview-md"></div>
                    <div class="avatar-preview preview-sm"></div>
                  </div>
                </div>

                <div class="row avatar-btns">
                  <div class="col-md-9">
                    <div class="btn-group">
                      <button type="button" class="btn btn-primary" data-method="rotate" data-option="-90" title="Rotate -90 degrees">Rotate Left</button>
                      <button type="button" class="btn btn-primary" data-method="rotate" data-option="-15">-15deg</button>
                      <button type="button" class="btn btn-primary" data-method="rotate" data-option="-30">-30deg</button>
                      <button type="button" class="btn btn-primary" data-method="rotate" data-option="-45">-45deg</button>
                    </div>
                    <div class="btn-group">
                      <button type="button" class="btn btn-primary" data-method="rotate" data-option="90" title="Rotate 90 degrees">Rotate Right</button>
                      <button type="button" class="btn btn-primary" data-method="rotate" data-option="15">15deg</button>
                      <button type="button" class="btn btn-primary" data-method="rotate" data-option="30">30deg</button>
                      <button type="button" class="btn btn-primary" data-method="rotate" data-option="45">45deg</button>
                    </div>
                  </div>
                  <div class="col-md-3">
                    <button type="submit" class="btn btn-primary btn-block avatar-save">Done</button>
                  </div>
                </div>
              </div>
            </div>
            <!-- <div class="modal-footer">
              <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
            </div> -->
          </form>
        </div>
      </div>
    </div><!-- /.modal -->

    <!-- Loading state -->
    <div class="loading" aria-label="Loading" role="img" tabindex="-1"></div>
  </div>

  <script src="js/jquery.min.js"></script>
  <script src="js/bootstrap.min.js"></script>
  <script src="js/cropper/cropper.min.js"></script>
  <script src="js/main.js"></script>
</body>
</html>

STEP 4 – Proses Upload
Setelah kita buat tampilannya sekarang kita buat untuk proses upload gambarnya. Buat sebuah file dengan nama crop.php, lalu simpan pada fodler xampp/htdocs/crop_upload/. Berikut skripnya :

<?php
class CropAvatar {
  private $src;
  private $data;
  private $dst;
  private $type;
  private $extension;
  private $msg;

  function __construct($src, $data, $file) {
    $this -> setSrc($src);
    $this -> setData($data);
    $this -> setFile($file);
    $this -> crop($this -> src, $this -> dst, $this -> data);
  }

  private function setSrc($src) {
    if (!empty($src)) {
      $type = exif_imagetype($src);

      if ($type) {
        $this -> src = $src;
        $this -> type = $type;
        $this -> extension = image_type_to_extension($type);
        $this -> setDst();
      }
    }
  }

  private function setData($data) {
    if (!empty($data)) {
      $this -> data = json_decode(stripslashes($data));
    }
  }

  private function setFile($file) {
    $errorCode = $file['error'];
    
    if ($errorCode === UPLOAD_ERR_OK) {
      $type = exif_imagetype($file['tmp_name']);

      if ($type) {
        $extension = image_type_to_extension($type);
        $src = 'images/' . date('YmdHis') . '.original' . $extension;

        if ($type == IMAGETYPE_GIF || $type == IMAGETYPE_JPEG || $type == IMAGETYPE_PNG) {

          if (file_exists($src)) {
            unlink($src);
          }

          $result = move_uploaded_file($file['tmp_name'], $src);

          if ($result) {
            $this -> src = $src;
            $this -> type = $type;
            $this -> extension = $extension;
            $this -> setDst();
          } else {
             $this -> msg = 'Failed to save file';
          }
        } else {
          $this -> msg = 'Please upload image with the following types: JPG, PNG, GIF';
        }
      } else {
        $this -> msg = 'Please upload image file';
      }
    } else {
      $this -> msg = $this -> codeToMessage($errorCode);
    }
  }

  private function setDst() {
    $this -> dst = 'images/' . date('YmdHis') . '.png';
  }

  private function crop($src, $dst, $data) {
    if (!empty($src) && !empty($dst) && !empty($data)) {
      switch ($this -> type) {
        case IMAGETYPE_GIF:
          $src_img = imagecreatefromgif($src);
          break;

        case IMAGETYPE_JPEG:
          $src_img = imagecreatefromjpeg($src);
          break;

        case IMAGETYPE_PNG:
          $src_img = imagecreatefrompng($src);
          break;
      }

      if (!$src_img) {
        $this -> msg = "Failed to read the image file";
        return;
      }

      $size = getimagesize($src);
      $size_w = $size[0]; // natural width
      $size_h = $size[1]; // natural height

      $src_img_w = $size_w;
      $src_img_h = $size_h;

      $degrees = $data -> rotate;

      // Rotate the source image
      if (is_numeric($degrees) && $degrees != 0) {
        // PHP's degrees is opposite to CSS's degrees
        $new_img = imagerotate( $src_img, -$degrees, imagecolorallocatealpha($src_img, 0, 0, 0, 127) );

        imagedestroy($src_img);
        $src_img = $new_img;

        $deg = abs($degrees) % 180;
        $arc = ($deg > 90 ? (180 - $deg) : $deg) * M_PI / 180;

        $src_img_w = $size_w * cos($arc) + $size_h * sin($arc);
        $src_img_h = $size_w * sin($arc) + $size_h * cos($arc);

        // Fix rotated image miss 1px issue when degrees < 0
        $src_img_w -= 1;
        $src_img_h -= 1;
      }

      $tmp_img_w = $data -> width;
      $tmp_img_h = $data -> height;
      $dst_img_w = 220;
      $dst_img_h = 220;

      $src_x = $data -> x;
      $src_y = $data -> y;

      if ($src_x <= -$tmp_img_w || $src_x > $src_img_w) {
        $src_x = $src_w = $dst_x = $dst_w = 0;
      } else if ($src_x <= 0) {
        $dst_x = -$src_x;
        $src_x = 0;
        $src_w = $dst_w = min($src_img_w, $tmp_img_w + $src_x);
      } else if ($src_x <= $src_img_w) {
        $dst_x = 0;
        $src_w = $dst_w = min($tmp_img_w, $src_img_w - $src_x);
      }

      if ($src_w <= 0 || $src_y <= -$tmp_img_h || $src_y > $src_img_h) {
        $src_y = $src_h = $dst_y = $dst_h = 0;
      } else if ($src_y <= 0) {
        $dst_y = -$src_y;
        $src_y = 0;
        $src_h = $dst_h = min($src_img_h, $tmp_img_h + $src_y);
      } else if ($src_y <= $src_img_h) {
        $dst_y = 0;
        $src_h = $dst_h = min($tmp_img_h, $src_img_h - $src_y);
      }

      // Scale to destination position and size
      $ratio = $tmp_img_w / $dst_img_w;
      $dst_x /= $ratio;
      $dst_y /= $ratio;
      $dst_w /= $ratio;
      $dst_h /= $ratio;

      $dst_img = imagecreatetruecolor($dst_img_w, $dst_img_h);

      // Add transparent background to destination image
      imagefill($dst_img, 0, 0, imagecolorallocatealpha($dst_img, 0, 0, 0, 127));
      imagesavealpha($dst_img, true);

      $result = imagecopyresampled($dst_img, $src_img, $dst_x, $dst_y, $src_x, $src_y, $dst_w, $dst_h, $src_w, $src_h);

      if ($result) {
        if (!imagepng($dst_img, $dst)) {
          $this -> msg = "Failed to save the cropped image file";
        }
      } else {
        $this -> msg = "Failed to crop the image file";
      }

      imagedestroy($src_img);
      imagedestroy($dst_img);
    }
  }

  private function codeToMessage($code) {
    $errors = array(
      UPLOAD_ERR_INI_SIZE =>'The uploaded file exceeds the upload_max_filesize directive in php.ini',
      UPLOAD_ERR_FORM_SIZE =>'The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form',
      UPLOAD_ERR_PARTIAL =>'The uploaded file was only partially uploaded',
      UPLOAD_ERR_NO_FILE =>'No file was uploaded',
      UPLOAD_ERR_NO_TMP_DIR =>'Missing a temporary folder',
      UPLOAD_ERR_CANT_WRITE =>'Failed to write file to disk',
      UPLOAD_ERR_EXTENSION =>'File upload stopped by extension',
    );

    if (array_key_exists($code, $errors)) {
      return $errors[$code];
    }

    return 'Unknown upload error';
  }

  public function getResult() {
    return !empty($this -> data) ? $this -> dst : $this -> src;
  }

  public function getMsg() {
    return $this -> msg;
  }
}

$crop = new CropAvatar(
  isset($_POST['avatar_src']) ? $_POST['avatar_src'] : null,
  isset($_POST['avatar_data']) ? $_POST['avatar_data'] : null,
  isset($_FILES['avatar_file']) ? $_FILES['avatar_file'] : null
);

$response = array(
  'state'  => 200,
  'message' => $crop -> getMsg(),
  'result' => $crop -> getResult()
);

echo json_encode($response);

Dari kedua koding di atas mungkin sudah sedikit jelas ya kawan karena memang sudah sangat jelas dari setiap koding yang saya buat untuk membuat sebuah fungsi cropper gambar.


Source Code
Untuk mengunduh source code nya. Klik Disini
Bingung cara downloadnya? klik disini untuk melihat caranya.


Sekian untuk catatan kali ini. Semoga catatan ini bisa bermanfaat. Apabila ada yang ingin ditanyakan, langsung tanyakan saja lewat form komentar dibawah ini. Terimakasih.


Sumber & Referensi
Dokumentasi Bootstrap : http://getbootstrap.com/getting-started/
JQuery Cropper : https://fengyuanchen.github.io/cropper

Cara Mudah Membuat Crop Gambar Plus Upload dengan PHP, Tutorial Membuat Crop Gambar Plus Upload dengan PHP, Tutorial membuat Crop dan Upload gambar dengan PHP, Cara Membuat Crop dan Upload Gambar dengan PHP, Tutorial membuat Upload dan Crop gambar dengan PHP, Cara Membuat Upload dan Crop gambar dengan PHP

Crop

(Total : 1,278 viewers, 1 viewers today)
cara-membuat-crop-gambar-plus-upload-dengan-php

ABOUT THE AUTHOR

Interested in android programming, long time focused on web development. Visit My Profile Site at www.rizaldimaulidia.com

POST YOUR COMMENTS

Your email address will not be published. Required fields are marked *

Name *

Email *

Website

NOTE ARCHIVES