Skip Loading

[HTML5] Cara menyimpan canvas image sebagai file bitmap

Fitur HTML 5 yang paling menarik bagi saya adalah elemen canvas. Canvas bisa dikatakan adalah salah satu fitur "adobe flash killer", selain juga dukungan html 5 terhadap file video. Dengan canvas kita dapat melakukan hal-hal yang dulu hanya bisa dilakukan dengan adobe flash, seperti manipulasi bitmap, menggambar graphic, animasi hingga menampilkan 3D image.

Pada artikel ini saya akan memberikan tutorial untuk menyinpan data Canvas sebagai file bitmap dan mengupload ke server.

Untuk mempercepat tutorial, saya akan menggunakan library javascript sketch yang dapat membuat aplikasi drawing sederhana. Sketch,js dapat anda download di http://intridea.github.io/sketch.js/

Kode untuk membuat aplikasi drawing sederhana adalah sbb:

<html>
    <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>
    <script type="text/javascript" src="http://intridea.github.com/sketch.js/lib/sketch.min.js"></script>
    <style>
        #demo{
            margin:0 auto;
            width: 800px;
        }
        .tools {
            margin-bottom: 10px;
        }
        .tools a {
            border: 1px solid black;
            color: black;
            display: inline-block;
            font-weight: bold;
            height: 30px;
            line-height: 30px;
            padding: 0 10px;
            text-align: center;
            text-decoration: none;
            vertical-align: middle;
        }
        canvas {
            border: 1px solid #ccc;
            height: 300px;
            width: 800px;
        }
    </style>
    <body>
        <div id='demo'>
            <div class='tools'>
                
            </div>
            <canvas id='colors_sketch' width='800' height='300'></canvas>
            <script type='text/javascript'>
                $(function () {
                    $.each(['#f00', '#ff0', '#0f0', '#0ff', '#00f', '#f0f', '#000', '#fff'], function () {
                        $('#demo .tools').append("<a href='#colors_sketch' data-color='" + this + "' style='width: 10px; background: " + this + ";'></a> ");
                    });
                    $.each([3, 5, 10, 15], function () {
                        $('#demo .tools').append("<a href='#colors_sketch' data-size='" + this + "' style='background: #ccc'>" + this + "</a> ");
                    });
                    $('#colors_sketch').sketch();
                });
            </script>
        </div>
    </body>
</html>

Untuk mengambil data bitmap dari canvas sangat mudah, hanya menggunkan perintah javascript:  canvas.toDataURL('image/jpeg') untuk menyimpan sebagai image jpg atau canvas.toDataURL('image/png') untuk menyimpan sebagai image png.

Code untuk menyimpan di client side (browser) adalah sebagai berikut:

<canvas id='colors_sketch' width='800' height='300'></canvas><br/><br/>
<a class="button" id="btn-download" download="my-file-name.png">Save As PNG</a>
<a class="button" id="btn-download2" download="my-file-name.jpg">Save As JPG</a>

<script type='text/javascript'>
       var canvas = document.getElementById('colors_sketch');
       $(function () {
                    $("#btn-download").click(function (e) {
                        var dataURL = canvas.toDataURL('image/png');
                        this.href = dataURL;
                    });
                    $("#btn-download2").click(function (e) {
                        var dataURL = canvas.toDataURL('image/jpeg');
                        this.href = dataURL;
                    });
                    
         });
</script>

Pada code di atas, saya menambahkan 2 link button, dengan sedikit trick agar browser membuka window save.

Sekarang bagaimana agar kita dapat mengupload data bitmap ke server dan menyimpannya sebagai file png atau jpg? Untuk itu saya akan membuat file php dengan nama upload.php, dan pada file html akan saya tambahkan button untuk mengupload dengan menggunakan ajax.

Code htmlnya :

<canvas id='colors_sketch' width='800' height='300'></canvas><br/><br/>
            <a class="button" id="btn-download" download="my-file-name.png">Save As PNG</a>
            <a class="button" id="btn-download2" download="my-file-name.jpg">Save As JPG</a>
            <a class="button" id="btn-upload">Upload To Server</a>
<div id="uploaded">
                
 </div>
 <script type='text/javascript'>
                var canvas = document.getElementById('colors_sketch');
                $(function () {
                    $.each(['#f00', '#ff0', '#0f0', '#0ff', '#00f', '#f0f', '#000', '#fff'], function () {
                        $('#demo .tools').append("<a href='#colors_sketch' data-color='" + this + "' style='width: 10px; background: " + this + ";'></a> ");
                    });
                    $.each([3, 5, 10, 15], function () {
                        $('#demo .tools').append("<a href='#colors_sketch' data-size='" + this + "' style='background: #ccc'>" + this + "</a> ");
                    });
                    $('#colors_sketch').sketch();
                    $("#btn-download").click(function (e) {
                        var dataURL = canvas.toDataURL('image/png');
                        this.href = dataURL;
                    });
                    $("#btn-download2").click(function (e) {
                        var dataURL = canvas.toDataURL('image/jpeg');
                        this.href = dataURL;
                    });
                    $("#btn-upload").click(function (e) {
                        $.ajax({
                            type: "POST",
                            url: "upload.php",
                            data: {imgdata: canvas.toDataURL('image/jpg')},
                            dataType: "json",
                            beforeSend: function () {
                                $("#uploaded").html("");
                            },
                            error: function (jqXHR, textStatus, errorThrown) {
                                alert(errorThrown);
                            },
                            success: function (response) {
                                if (response.success) {
                                    imageurl = response.imageurl;
                                    $("#uploaded").html("<img src='" + imageurl +"'>");
                                    alert("upload suscess");
                                } else {
                                    alert("upload error");
                                }
                            }
                        });
                    });
                });
</script>

Pada code html di atas, saya akan mengupload ke upload.php dan akan menampilkan image yang sudah diupload ke div#uploaded. Caranya sama seperti sebelumnya, yaitu dengan canvas.toDataURL('image/jpeg') (Penting: Bukan image/jpg tetapi image/jpeg) untuk upload sebagai image jpg atau canvas.toDataURL('image/png') untuk upload sebagai image png.

Sedangan code phpnya adalah sbb:

upload.php

<?php

header('Content-Type: application/json');
$data = $_POST['imgdata'];
if ($data != "") {
    try {
        $filename = "photo_" . time() . '.jpg';
        $file = "./upload/" . $filename;
        $uri = substr($data, strpos($data, ",") + 1);
        file_put_contents($file, base64_decode($uri));
        echo json_encode(array("success" => "ok", "imageurl" => "upload/".$filename);
    } catch (Exception $e) {
        echo json_encode(array("message" => "error"));
    }
}

Bila upload sebagai png, maka ganti extension file menjadi ".png". perhatikan 2 baris berikut ini yang merupakan fungsi untuk menyimpan data bitmap menjadi file image :

$uri = substr($data, strpos($data, ",") + 1);
file_put_contents($file, base64_decode($uri));

Hasil dari perintah javascript canvas.toDataUrl adalah string yang dimulai dengan "image/png;base64," atau "image/jpeg;base64,". Untuk menyimpannya sebagai file, kita perlu menghilangkan header tersebut dengan perintah php substr($data, strpos($data, ",") + 1); Kemudian kita tinggal mengubahnya menjadi base64 dengan perintah base64_decode($uri), dan menyimpannya sebagai file.

Menambah background

Bila kita mencoba code di atas, maka akan menghasilkan image transparant png, dan image dengan background hitam bila upload sebagai Jpeg. Hal ini disebabkan karena data bitmap yang dihasilkan canvas pada dasarnya adalah transparant.. tentunya tidak menjadi masalah bila kita memang ingin menyimpan sebagai png, namun bila kita ingin menyimpan sebagai jpeg tentunya hal ini tidak kita inginkan.. Untuk itu kita perlu menambahkan background image di upload.php, sedangkan pada html kita gunakan  canvas.toDataURL('image/png'). Yup kita akan mengupload sebagai png agar mendapatkan image transparan, yang nantinya kita gabungkan dengan warna background.

upload.php

<?php

header('Content-Type: application/json');
$data = $_POST['imgdata'];
if ($data != "") {
    try {
        $filename = "photo_" . time().".jpg";
        $file = "./upload/" . $filename;
        $uri = substr($data, strpos($data, ",") + 1);
        $img = imagecreatefromstring(base64_decode($uri));
        $width = imagesx($img);
        $height = imagesy($img);
        $backgroundImg = imagecreatetruecolor($width, $height);
        $color = imagecolorallocate($backgroundImg, 255, 255, 255);
        imagefill($backgroundImg, 0, 0, $color);
        imagecopy($backgroundImg, $img, 0, 0, 0, 0, $width, $height);
        imagejpeg($backgroundImg,  $file, 100);
        echo json_encode(array("success" => "ok", "imageurl" => "upload/".$filename));
    } catch (Exception $e) {
        echo json_encode(array("message" => "error"));
    }
}

Pada listing code di atas, kita tidak langsung menyimpan bitmap data sebagai file, melainkan kita membuat image resource dengan perintah imagecreatefromstring(base64_decode($uri)); Kemudian untuk mendapatkan width&height dari image resource tersebut kita gunakan imagesx($img) danimagesy($img);. Selanjutnya buat background image dengan width&height yang sama, imagecreatetruecolor($width, $height);, yang kemudian kita fill dengan warna background, $color = imagecolorallocate($backgroundImg, 255,255, 255) , dengan perintah php ini saya membuat background putih (RGB(255,255,255). Setelah itu kita tinggal menggabungkan kedua image tersebut dengan perintah imagecopy($backgroundImg, $img, 0, 0, 0, 0, $width, $height); Kemudian simpan dalam bentuk file jpg dengan perintah: imagejpeg($backgroundImg, $file, 100);, dimana 100 adalah quality yang diinginkan (0-100) .

Untuk contoh lengkapnya lihat di sini.

www.paulussetyo.com

Related Posts
Comments ( 0 )
Add Comment

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