Using Canvas method toDataURL, I would like to be able to save the image on the server side (using Rails).
With toDataURL string, how to use it in a form that can be seen as a file attachment in a HTML form ?
To save a new Canvas document:Choose File | Save As. In the Save As dialog box, select a location to store the document and type a file name. Click Save to store the document on disk.
You can save a canvas to an image file by using the method canvas. toDataURL() , that returns the data URI for the canvas' image data.
Solution using jQuery, Paperclip, datafy.rb http://gist.github.com/397615
Here is my solution:
The Presentation page:
<html>
<!-- by [email protected] - on december/2012 -->
<script language='javaScript'>
// Check for the various File API support.
    if (window.File && window.FileReader && window.FileList && window.Blob) {
      // Great success! All the File APIs are supported.
    } else {
        alert('Este Browser não suporte a API Files');
    }
    function Compactar(Elemento) {
        var file = document.getElementById(Elemento), 
            reader = new FileReader(),      // métodos assíncronos, por isso os eventos!
            form = document.getElementById('frmFotos');
        //alert(file.id);
        reader.readAsDataURL(file.files[0]);            // aqui a abertura do arquivo, que irá disparar a função acima
        reader.onloadend = function() {     // aqui um evento, que será disparado na primeira linha abaixo da função chamada 
            var image = new Image();
            image.src = reader.result;      // vai disparar o tratamento do evento abaixo
            image.onload = function() {
                var maxWidth = 800,
                    maxHeight = 600,
                    width = image.width,
                    height = image.height;
                // calculate the width and height, constraining the proportions
                if (width > height) {
                    if (width > maxWidth) {
                      //height *= max_width / width;
                      height = Math.round(height *= maxWidth / width);
                      width = maxWidth;
                    }
                } else {
                    if (height > maxHeight) {
                      //width *= max_height / height;
                      width = Math.round(width *= maxHeight / height);
                      height = maxHeight;
                    }
                }
                var canvas = document.createElement('canvas');
                canvas.width = width;
                canvas.height = height;
                var ctx = canvas.getContext("2d");
                ctx.drawImage(image, 0, 0, maxWidth, maxHeight);
                // The resized file ready for upload
                var finalFile = canvas.toDataURL("image/jpeg",0.8);     //a 80% de qualidade
                // aqui cria-se novo input comun!
                /*var newinput = document.createElement("input");
                newinput.type = 'text';
                newinput.name = "edt" & Elemento;
                newinput.value = finalFile; // put result from canvas into new hidden input
                form.appendChild(newinput);*/
                document.getElementById("edtArq_1").value = finalFile;
                var preview = document.getElementById('preview');
                //alert(preview.id);
                preview.appendChild(canvas); // do the actual resized preview
            }
        }       
    }
</script>
<html>
<form id="form" action="submit" method="post" accept-charset="utf-8" enctype="multipart/form-data">
<!-- this will be left behind - we don't want to upload Mbytes of information -->
<input type='file' name='Arq_1' id='Arq_1' size='50' onchange='Compactar("Arq_1");'>
<form method="POST" id='frmFotos' action='SalvaArquivo.asp'>
<!-- this could be a hidden element -->
<input name='edtArq_1' id='edtArq_1'><br>
<input type='submit' name ='cmdEnviar' id='cmdEnviar' value='Enviar' >
</form>
<!-- just for you see the new resized image - no upload too -->
<div id="preview"></div>
</html>
The page that will reveive the request from the first page and save the image:
<html>
<!-- by [email protected] - on december/2012 -->
<!-- this script could be avoided if I had put the img element in the page directly 
. By the way, actualyy there's no necessity of showing nothing to user 
 -->
<script language='JavaScript'>
    var newImg = document.createElement("img");
    newImg.src = '<%=request.form("edtArq_1")%>';
    document.body.appendChild(newImg);
</script>
<body>
<input name='edtOriginal' value='<%=request.form("edtArq_1")%>'>
<%
' the data is encoded, so, we will need to deencode it ...
Function Base64Decode(ByVal base64String)
  'rfc1521
  '1999 Antonin Foller, Motobit Software, http://Motobit.cz
  Const Base64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
  Dim dataLength, sOut, groupBegin
  'remove white spaces, If any
  base64String = Replace(base64String, vbCrLf, "")
  base64String = Replace(base64String, vbTab, "")
  base64String = Replace(base64String, " ", "")
  'The source must consists from groups with Len of 4 chars
  dataLength = Len(base64String)
  If dataLength Mod 4 <> 0 Then
    Err.Raise 1, "Base64Decode", "Bad Base64 string."
    Exit Function
  End If
  ' Now decode each group:
  For groupBegin = 1 To dataLength Step 4
    Dim numDataBytes, CharCounter, thisChar, thisData, nGroup, pOut
    ' Each data group encodes up To 3 actual bytes.
    numDataBytes = 3
    nGroup = 0
    For CharCounter = 0 To 3
      ' Convert each character into 6 bits of data, And add it To
      ' an integer For temporary storage.  If a character is a '=', there
      ' is one fewer data byte.  (There can only be a maximum of 2 '=' In
      ' the whole string.)
      thisChar = Mid(base64String, groupBegin + CharCounter, 1)
      If thisChar = "=" Then
        numDataBytes = numDataBytes - 1
        thisData = 0
      Else
        thisData = InStr(1, Base64, thisChar, vbBinaryCompare) - 1
      End If
      If thisData = -1 Then
        Err.Raise 2, "Base64Decode", "Bad character In Base64 string."
        Exit Function
      End If
      nGroup = 64 * nGroup + thisData
    Next
    'Hex splits the long To 6 groups with 4 bits
    nGroup = Hex(nGroup)
    'Add leading zeros
    nGroup = String(6 - Len(nGroup), "0") & nGroup
    'Convert the 3 byte hex integer (6 chars) To 3 characters
    pOut = Chr(CByte("&H" & Mid(nGroup, 1, 2))) + _
      Chr(CByte("&H" & Mid(nGroup, 3, 2))) + _
      Chr(CByte("&H" & Mid(nGroup, 5, 2)))
    'add numDataBytes characters To out string
    sOut = sOut & Left(pOut, numDataBytes)
  Next
  Base64Decode = sOut
End Function
' now, we will save the data (new image) using the old FileSystemObject !!!
Set fso = Server.CreateObject ("Scripting.FileSystemObject")
If Err.Number <> 0 Then
    Response.write "Não foi possível instanciar objeto fso!<br>" & Err.description
    response.end
End if
dim Caminho, objArq
Caminho = Server.MapPath("./images")   'where I saved the new image
response.write Caminho
If Err.Number <> 0 Then
    Response.write "Não foi possível localizar caminho! " & Caminho & "<br>" & Err.description & "<br>"
else
    Set oFile = fso.CreateTextFile(Caminho & "\Teste.jpg", true)
    oFile.Write Base64Decode(replace(request.form("edtArq_1"), "data:image/jpeg;base64,", "")) 'BinaryToString(request.from("edtArq_1"))
    If Err.Number <> 0 Then
        Response.write "Não foi possível localizar thum(s)!" & Caminho & "<br>" & Err.description & "<br>"
    end if
    oFile.close
end if
%>
</body>
</html>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With