LiveCode LessonsLiveCode 6.5 Server GraphicsHow do I use LiveCode graphics features server-side?

How do I use LiveCode graphics features server-side?

Uploading and storing an image with a HTML upload form

Uploading and storing an image with a HTML upload form

The first step is to allow the user to upload an image. We're going to use a simple HTML upload form as discussed in the previous lesson, with the slight alteration of printing the HTML using our own handler, printForm, as this will make our code neater on the whole as we progress:

on printForm
          put "Upload an image:<br>"
          put "<form action='manip.lc' enctype='multipart/form-data' method='post'>"
 \         put "<input type='file' name='imagefile'><br>"
 \         put "<input type='submit' value='upload'>"
          put "</form>"
end printForm

This allows the user to upload an image, but after posting the data to the page, we obviously need to do something with it to store it. We'll do this by using the data in the $_FILES array. We're also going to use sessions to preserve data between posts to the page:

<?lc
start session
## enter the binary data of the image file into our $_SESSION if one's just been uploaded
if $_FILES["imagefile"] is not empty then
          put url("binfile:" & $_FILES["imagefile"]["filename"]) into $_SESSION["imagedata"]
end if
if $_SESSION["imagedata"] is empty then
          printForm ## no image has been uploaded so display the form to upload one
else
   ## here's where we're going to do the fun stuff       
end if
## print upload form
on printForm
          put "Upload an image:<br>"
 \         put "<form action='manip.lc' enctype='multipart/form-data' method='post'>"
 \         put "<input type='file' name='imagefile'><br>"
 \         put "<input type='submit' value='upload'>"
          put "</form>"
end printForm
stop session
?>

The above code will put the raw binary data of the image file into our $_SESSION array if it is present, and present the form to upload an image if it is not.

Creating and displaying the image using the uploaded data

Creating and displaying the image using the uploaded data

Now that we have the image data available to us, we're going to create an image object in LiveCode, and load the data into the object so that we can manipulate it. We're then going to use the export snapshot command to create a PNG image file from the object, which we can display to the user by printing some HTML:

if $_SESSION["imagedata"] is empty then
 \         printForm ## no image has been uploaded so display the form to upload one
else
          create image "myImage"
          set the lockLoc of image "myImage" to true ## this stops the image from being automatically resized at any point
          set the text of image "myImage" to $_SESSION["imagedata"]

 \         if $_SESSION["random"] is empty then put random(10000000) into $_SESSION["random"]
          export snapshot from image "myImage" to file ($_SESSION["random"] & ".png") as PNG
          put "<img src=" & quote & ($_SESSION["random"] & ".png") & quote & "></img><br><br>"
end if

We set the text property of the image to the imagedata contained in our $_SESSION array. The text property is used for the binary data of the image object. We are also creating a new value in our $_SESSION array if it is not present, $_SESSION["random"]. This is going to be used as a unique identifier that we use to refer to the user's image file during the duration of the session.

We then use the export snapshot command to export a png image from the image object, to a file which is named using the random value in the $_SESSION array. We now have an image file residing in the same directory as the server script. As a side-note, this also helps to make sure that the uploaded file is safe and free of malicious code, because by exporting a brand new image from the image file, any embedded code will be stripped out. We then display the image by printing an <img> tag and referring to the file we just created.

Accepting user input to carry out image manipulation

Accepting user input to carry out image manipulation

We're going to print some forms to allow the user to enter the operations they want to perform on the image. We'll use a printOptions handler to print these forms, like we did with the upload form:

on printOptions

 \         put "<p>Set image dimensions<br>"
          put "<p><form action='manip.lc' method='post'>"
          put "<input type='text' name='width'>"
          put "<input type='text' name='height'>"
          put "<input type='submit' value='Apply'>"
          put "</form></p>"


 \         put "<p>Strip a hue from the image<br>"
          put "<form action='manip.lc' method='post'>"
          put "<input type='radio' name='huestrip' value='2'>Red"
          put "<input type='radio' name='huestrip' value='3'>Green"
          put "<input type='radio' name='huestrip' value='4'>Blue"
          put "<input type='submit' value='apply'>"
          put "</form></p>"

 \         put "<p>Add Color<br>"
          put "<form action='manip.lc' method='post'>"
          put "<input type='radio' name='hueadd' value='2'>Red"
          put "<input type='radio' name='hueadd' value='3'>Green"
          put "<input type='radio' name='hueadd' value='4'>Blue"
          put "<input type='text' name='saturation'>Saturation"
          put "<input type='submit' value='apply'>"
          put "</form></p>"

 \         put "<a href='logout.lc'>Reset Session</a>"

end printOptions

This will display 3 forms to the user to allow them to perform a variety of operations on the image. It also creates a button that sends the user to a page that destroys their session, so that they can start over if they want. These forms post the user's input back to the page. We now need to change our main block of code to read the $_POST array to determine what the user wants to do:

if $_SESSION["imagedata"] is empty then
          printForm ## no image has been uploaded so display the form to upload one
else
          create image "myImage"
          set the lockLoc of image "myImage" to true
          set the text of image "myImage" to $_SESSION["imagedata"]

          repeat for each key tOption in $_POST
                     if $_POST[tOption] is not empty then applyOption tOption
          end repeat

          if $_SESSION["random"] is empty then put random(10000000) into $_SESSION["random"]
 \         export snapshot from image "myImage" to file ($_SESSION["random"] & ".png") as PNG
          put "<img src=" & quote & ($_SESSION["random"] & ".png") & quote & "></img><br><br>"
          put url("binfile:" & $_SESSION["random"] & ".png") into $_SESSION["imagedata"]

 \         printOptions
end if

Here you can see the alterations we've made in the highlighted lines. We repeat through the $_POST array and call another handler, applyOptions (which will be detailed in the next section) based on the contents. After doing the alterations and displaying the image, we also update the imagedata in our session array with the altered data. We call the printOptions handler at the bottom in order to print the forms for user input.

Performing the image manipulation

Performing the image manipulation

The actual alteration of the image object we create is done using the applyOption handler we're about to write. We're going to allow the user to do 3 things - resize the image, 'strip' a colour channel from the image, and add an integer value to a colour channel in the image. These are very simple, crude operations, but showcase what we can do quite effectively.

on applyOption pOption

          switch pOption
                     case "width"
 \                               if $_POST["width"] is not a number then
 \                                          put "WIDTH NEEDS TO A NUMBER<br>"
 \                               else
                                          set the width of image "myImage" to $_POST["width"]
                                end if
                                break
                     case "height"
 \                               if $_POST["height"] is not a number then
                                           put "HEIGHT NEEDS TO BE A NUMBER<br>"
                                else
                                           set the height of image "myImage" to $_POST["height"]
                                end if
                                break
                     case "huestrip"
 \                               put the imageData of image "myImage" into tImageDat
                                repeat with x = $_POST["huestrip"] to the number of chars in tImageDat step 4
                                           put numtochar(0) into char x of tImageDat
                                end repeat
 \                               set the imageData of image "myImage" to tImageDat
                                break
                      case "hueadd"
                                if ($_POST["hueadd"] >= 0) and ($_POST["hueadd"] <= 255) then
                                           put the imageData of image "myImage" into tImageDat
                                           repeat with x = $_POST["hueadd"] to the number of chars in tImageDat step 4
 \                                                     put numtochar($_POST["saturation"]) into char x of tImageDat
                                           end repeat
 \                                          set the imageData of image "myImage" to tImageDat
                                else
                                           put "NEEDS TO BE AN INTEGER 0-255"
                                end if
                                break
          end switch

end applyOption

We switch based on the parameter pOption (which is derived from the $_POST array). Width and height are very simple, we just set the width or height property of the image to whatever the user entered. The more complex ones are huestrip and hueadd, both of which directly manipulate the imageData property of the image.

The imageData property is essentially a bitmap representation of the image. Each pixel in the image is represented by a group of 4 characters (bytes) in the imageData, in sequence. The first character in each pixel is the alpha channel (transparency), the second is the red channel, the third green, and the fourth blue.

Huestrip loops through the imagedata and sets either every 2nd, 3rd, or 4th pixel to 0, effectively stripping that channel out of the image. Hueadd works in much the same way, except that it adds the user-submitted value to every 2nd, 3rd, or 4th pixel.

Code in full

<?lc
start session
## enter the image file into our $_SESSION if one's just been uploaded
if $_FILES["imagefile"] is not empty then
          put url("binfile:" & $_FILES["imagefile"]["filename"]) into $_SESSION["imagedata"]
end if
if $_SESSION["imagedata"] is empty then
          printForm ## no image has been uploaded so display the form to upload one
else
          create image "myImage"
          set the lockLoc of image "myImage" to true
          set the text of image "myImage" to $_SESSION["imagedata"]

          repeat for each key tOption in $_POST
                     if $_POST[tOption] is not empty then applyOption tOption
          end repeat

          if $_SESSION["random"] is empty then put random(10000000) into $_SESSION["random"]
          export snapshot from image "myImage" to file ($_SESSION["random"] & ".png") as PNG
          put "<img src=" & quote & ($_SESSION["random"] & ".png") & quote & "></img><br><br>"
          put url("binfile:" & $_SESSION["random"] & ".png") into $_SESSION["imagedata"]

 \         printOptions
end if
## apply an option to the image
on applyOption pOption

          switch pOption
                     case "width"
 \                               if $_POST["width"] is not a number then
 \                                          put "WIDTH NEEDS TO A NUMBER<br>"
 \                               else
                                           set the width of image "myImage" to $_POST["width"]
                                end if
                                break
                     case "height"
 \                               if $_POST["height"] is not a number then
                                           put "HEIGHT NEEDS TO BE A NUMBER<br>"
                                else
                                           set the height of image "myImage" to $_POST["height"]
                                end if
                                break
                     case "huestrip"
 \                               put the imageData of image "myImage" into tImageDat
                                repeat with x = $_POST["huestrip"] to the number of chars in tImageDat step 4
                                           put numtochar(0) into char x of tImageDat
                                end repeat
 \                               set the imageData of image "myImage" to tImageDat
                                break
                      case "hueadd"
                                if ($_POST["hueadd"] >= 0) and ($_POST["hueadd"] <= 255) then
                                           put the imageData of image "myImage" into tImageDat
                                           repeat with x = $_POST["hueadd"] to the number of chars in tImageDat step 4
 \                                                     put numtochar($_POST["saturation"]) into char x of tImageDat
                                           end repeat
 \                                          set the imageData of image "myImage" to tImageDat
                                else
                                           put "NEEDS TO BE AN INTEGER 0-255"
                                end if
                                break
          end switch

end applyOption
## print photo manipulation options
on printOptions

          put "<p>Set image dimensions<br>"
          put "<p><form action='manip.lc' method='post'>"
          put "<input type='text' name='width'>"
 \         put "<input type='text' name='height'>"
          put "<input type='submit' value='Apply'>"
          put "</form></p>"


 \         put "<p>Strip a hue from the image<br>"
          put "<form action='manip.lc' method='post'>"
          put "<input type='radio' name='huestrip' value='2'>Red"
          put "<input type='radio' name='huestrip' value='3'>Green"
          put "<input type='radio' name='huestrip' value='4'>Blue"
          put "<input type='submit' value='apply'>"
          put "</form></p>"

 \         put "<p>Add Color<br>"
          put "<form action='manip.lc' method='post'>"
          put "<input type='radio' name='hueadd' value='2'>Red"
          put "<input type='radio' name='hueadd' value='3'>Green"
          put "<input type='radio' name='hueadd' value='4'>Blue"
          put "<input type='text' name='saturation'>Saturation"
          put "<input type='submit' value='apply'>"
          put "</form></p>"

 \         put "<a href='logout.lc'>Reset Session</a>"

end printOptions
## print upload form
on printForm
          put "Upload an image:<br>"
          put "<form action='manip.lc' enctype='multipart/form-data' method='post'>"
          put "<input type='file' name='imagefile'><br>"
 \         put "<input type='submit' value='upload'>"
          put "</form>"
end printForm
stop session
?>

0 Comments

Add your comment

E-Mail me when someone replies to this comment