Posted on May 04, 2010 by Jimmy K. in Tutorials
I wanted to be able to track the number of views each one of my posts gets in a very general way so I could create a “popular articles” section on my blog. I looked through the MySQL database and couldn’t find any traces of WordPress tracking post views by default. So! What I did was write a nifty little set of functions that I’m pretty sure don’t follow any development standards.
Update: I’m slowly tackling the obstacle of converting this tutorial into a WordPress plugin.
First, I created a table in the MySQL database to keep track of the post views and I update the table every time a post is loaded in the browser. I only count specific post views (where ./?p=XYZ) is in the URL.
Here is the MySQL statement to create the table:
CREATE TABLE IF NOT EXISTS `wp_postviews_z` (`PostID` mediumint(8) unsigned NOT NULL, `NumViews` mediumint(8) unsigned NOT NULL) ENGINE=MyISAM DEFAULT CHARSET=utf8;
Then I wrote a function called jTrackPostView(), which basically updates the database whenever a post is being viewed. I placed this code into the index.php file. All it really does is says: if $_GET['p'] is set, call the jTrackPostView() function because we only want to track the post view if we’re actually reading the entire post (not the excerpt).
<?php print('This is PHP.'); ?>
To display the popular posts, I placed this code into the sidebar.php file:
<table style="width: 250px;">
<?php
$aViewCounts = array();
$oViewsQuery = mysql_query("SELECT `PostID`, `NumViews` FROM `wp_postviews_z` ORDER BY `NumViews` DESC LIMIT 10;") or die(mysql_error());
$sPopularQuery = "SELECT `ID`, `post_title` FROM `wp_posts` WHERE `ID` = '0'";
while ($oViewsResults = mysql_fetch_assoc($oViewsQuery)) {
$aViewCounts[$oViewsResults['PostID']] = $oViewsResults['NumViews'];
$sPopularQuery .= " OR `ID` = '" . $oViewsResults['PostID'] . "'";
}
$sPopularQuery .= " ORDER BY `post_title` ASC;";
$oQuery = mysql_query($sPopularQuery) or die(mysql_error());
$y = 0; while ($oResults = mysql_fetch_assoc($oQuery)) {
print('<tr style="width: 250px;">');
print('<td style="width: 250px;"><ul><li>');
print('<a href="./?p=' . $oResults['ID'] . '">' . $oResults['post_title'] . '</a> <span>(' . $aViewCounts[$oResults['ID']] . ')</span>');
print('</li></ul></td></tr>');
}
?>
</table>
I really want to help other people by converting this into a lightweight WordPress plugin, but I don’t know how to do that yet. Hopefully by the end of May I’ll be better equipped to tackle that.
Can someone please suggest where I can find a decent tutorial for writing WordPress plugins? If so, please let me know in the comments.
Continue Reading...
Posted on January 20, 2010 by Jimmy K. in Tutorials
I would like to thank Ryan (of rynotec.com) for bringing a small, yet hindering bug to my attention regarding the Pseudo-Captcha tutorial. It seems that I had accidentally typed a “Q” in the “W” spot on the character image that is read by end-users to prove that they are human.
He had implemented the Pseudo-Captcha script into a website that he was developing and the verification kept failing. He took a quick look at the character image and to his surprise (and mine), it had two Q’s in it. Needless to say, I am ashamed. How this travesty could have happened, I do not know. I must be slipping in my old age. I apologize. :)
Regardless, the tutorial and downloads are fixed and there is no need to worry.
Continue Reading...
Posted on August 19, 2009 by Jimmy K. in Tutorials
Recently, spammers have been taking complete advantage of my unmonitored, open comment-posting system with posts to inappropriate websites and medications. There was even one for Miley Cyrus. Seriously? Come on, I can’t have this crap on my site.
I developed a small Captcha-like system called Pseudo-Captcha (very clever, yes?). It basically reads two files: background.jpg, which contains a fancy graphic – I used clouds – and chars.png, which contains a strip of characters in the alphabet.
When called, the script selects a pre-defined number of random, squiggly letters, assigns those values to the $_SESSION['Captcha']['Values'] variable and pastes them over a background image. The composite is then output as a jpeg at run-time. Validation can be done by comparing any values entered by the user to the $_SESSION['Captcha']['Values'] variable using PHP’s built-in implode() function.
The script can be uploaded to any web server right out of the box as long as it supports PHP and sessions. Using it is quite simple, just peruse the example.php file to find anything you need. If you would like more information on it’s use, please leave a comment on this article.
The contents of captcha.php:
<?php
session_start();
header("content-type: image/jpeg");
require("./backend/captcha.php");
if (isset($_SESSION['Captcha']['Values'])) {
$aValues = $_SESSION['Captcha']['Values'];
} else {
// Generate some random values because we're noob..
$aValues = jGenerateCaptchaValues(5);
}
// Open the background/character images..
$oBackground = imagecreatefromjpeg("./images/background.jpg");
$oCharacters = imagecreatefrompng("./images/chars.png");
for ($i = 0; $i < sizeof($aValues); $i++) {
// Copy the calculated portion of the character image to the background..
imagecopyresampled($oBackground, $oCharacters, ($i * 92), 0, (array_search($aValues[$i], $GLOBALS['Captcha']['Values']) * 90), 0, 90, 90, 90, 90);
}
// Output the composite background..
imagejpeg($oBackground);
// Destroy the original images..
imagedestroy($oBackground);
imagedestroy($oCharacters);
?>
The contents of backend/captcha.php:
<?php
// Create an array to hold the available characters..
$GLOBALS['Captcha']['Values'] = preg_split("//", "ABCDEFGHIJKLMNOPQRSTUVWXYZ", -1, PREG_SPLIT_NO_EMPTY);
/* Generates an array of random values. */
function jGenerateCaptchaValues($iNumValues) {
$aRandomValues = array();
for ($i = 0; $i < $iNumValues; $i++) {
array_push($aRandomValues, $GLOBALS['Captcha']['Values'][rand(0, sizeof($GLOBALS['Captcha']['Values']) - 1)]);
}
return $aRandomValues;
}
?>
And finally, the contents of example.php:
<?php
session_start();
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><title>Pseudo-Captcha by END[SEVEN] Web Development</title>
<style type="text/css" media="all">
body { background-color: #FFFFFF; margin: 20px; }
img { border: 0px; }
</style>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head><body>
<?php
require("./backend/captcha.php");
$_SESSION['Captcha']['Values'] = jGenerateCaptchaValues(5);
$_SESSION['Captcha']['Values'] = array("T", "E", "S", "T", "O"); // Comment out this line..
?>
<img src="./captcha.php" alt="Authentication Image" />
</body></html>
Like I said, it’s very easy to use. I haven’t tested it with any of the spammers on this site yet, so I’m not sure if it will stop automated attacks or not, but it’s one more preventive step in the right direction (I think, anyway).
I’ve never attempted to download/install Captcha before, nor do I want to try. I just wanted a sweet background with a custom font so I could make it look like the rest of my site (it doesn’t right now, but maybe one day it will).
Click here to download the source files.
Update: I’ve tested it with spammers and it does work. We were getting rammed pretty hard by that Cialis bot. It was posting vulgar, inappropriate things in the comments section of each article and has since been blocked. There is a 2.5MB file if anyone wants to read it. :)
Update: I’ve recently converted my blog to use WordPress and there are plenty of plugins available for free online so this tutorial is pretty much useless now.
Continue Reading...
Posted on August 08, 2009 by Jimmy K. in Tutorials
For the purpose of being awesome, I set out to educate myself in the process of streaming (downstream) and publishing (upstream) live, uninterrupted audio/video using RTMP (Real Time Messaging Protocol). Click here if you would like to learn a more about RTMP.
Are you interested in writing your own webcam delivery, surveillance or online audio/video chat application? Good news! RTMP may be just the protocol that you need! I’ve created two small Adobe Flash (.fla) files that should get you started.
The first, upstream.swf, is the file you would use to upload your webcam’s video feed to an RTMP server. (Usually a hosting company or in-house terminal running Flash Media Server or Wowza Media Server.. I believe that both applications are free for up to 10 simultaneous streams).
The contents of upstream.fla:
var sMediaServerURL:String = "rtmp://[YOUR_RTMP_SERVER]";
var sStreamName:String = "[YOUR_RTMP_STREAM]";
var oCamera:Camera;
var oConnection:NetConnection;
var oMetaData:Object = new Object();
var oMicrophone:Microphone;
var oNetStream:NetStream;
var oVideo:Video = new Video(640, 480);
NetConnection.prototype.onBWDone = function(oObject1:Object) {
// Some media servers are dumb, so we have to catch a strange event.
// Just go ahead and trust me on this one.
trace("onBWDone: " + oObject1.toString());
}
this.oConnection = new NetConnection();
this.oConnection.addEventListener(NetStatusEvent.NET_STATUS, eNetStatus, false, 0, true);
this.oConnection.connect(this.sMediaServerURL);
function eNetStatus(oEvent1:NetStatusEvent) {
trace("NetStatusEvent: " + oEvent1.info.code);
if (oEvent1.info.code == "NetConnection.Connect.Success") {
trace("Connected to the RTMP server.");
this.oCamera = Camera.getCamera();
this.oMicrophone = Microphone.getMicrophone();
// These settings worked fairly well for my purposes.
this.oCamera.setMode(640, 480, 30, true);
// Some servers limit your bandwidth so you
// may have to adjust these numbers to suit your needs.
this.oCamera.setQuality(0, 80);
// Attach the camera to the video.
this.oVideo.attachCamera(this.oCamera);
this.addChild(oVideo);
// Create a stream for the connection..
this.oNetStream = new NetStream(oConnection);
// Attach the camera and microphone to the stream..
this.oNetStream.attachCamera(this.oCamera);
this.oNetStream.attachAudio(this.oMicrophone);
// Start publishing the stream..
this.oNetStream.publish(this.sStreamName);
// Listen for meta data..
this.oMetaData.onMetaData = eMetaDataReceived;
this.oNetStream.client = this.oMetaData;
} else if (oEvent1.info.code == "NetConnection.Connect.Closed") {
trace("Disconnected from the RTMP server.");
}
}
function eMetaDataReceived(oObject1:Object) {
trace("MetaData: " + oObject1.toString());
}
The second file, downstream.swf is the file you would use to view your webcam’s live video feed from the RTMP server. This file could also be exported to a SWF and embedded on your website to allow other people to view your stream.
The contents of downstream.fla:
var sMediaServerURL:String = "rtmp://[YOUR_RTMP_SERVER]";
var sStreamName:String = "[YOUR_RTMP_STREAM]";
var oConnection:NetConnection;
var oMetaData:Object = new Object();
var oNetStream:NetStream;
var oVideo:Video = new Video(640, 480);
this.oConnection = new NetConnection();
this.oConnection.addEventListener(NetStatusEvent.NET_STATUS, eNetStatus, false, 0, true);
this.oConnection.connect(this.sMediaServerURL);
function eNetStatus(oEvent1:NetStatusEvent) {
// Trace the event code for debugging..
trace("NetStatusEvent: " + oEvent1.info.code);
switch (oEvent1.info.code) {
case "NetConnection.Connect.Success":
trace("Connected to the stream!");
// Create a stream for the connection..
this.oNetStream = new NetStream(oConnection);
this.oNetStream.addEventListener(NetStatusEvent.NET_STATUS, eNetStatus, false, 0, true);
this.oNetStream.bufferTime = 5; // Set this to whatever is comfortable..
// Listen for meta data..
this.oMetaData.onMetaData = eMetaDataReceived;
this.oNetStream.client = this.oMetaData;
// Attach the stream to the stage..
this.oVideo.attachNetStream(oNetStream);
this.oNetStream.play(sStreamName);
this.addChildAt(this.oVideo, 0);
break;
case "NetStream.Play.StreamNotFound":
trace("This stream is currently unavialable.");
break;
}
}
function eMetaDataReceived(oObject1:Object) {
trace("MetaData: " + oObject1.toString());
}
The code for each file is fairly straight-forward: Create a NetConnection object to connect to the server, create a NetStream object to handle the stream, do something with the content of the stream (publish it if we’re broadcasting, download it if we’re viewing) and VIOLA!
Remember to replace [YOUR_RTMP_SERVER] with the URL that is provided to you by your RTMP hosting company (or localhost if you’re testing locally) and [YOUR_RTMP_STREAM] with the name of your stream (for multiple streams on the same server, this is the only part that will change).
Click here to download the source files.
Continue Reading...
Posted on August 05, 2009 by Jimmy K. in Tutorials
For the last couple of years, I’ve been running an online marketing website called BHI Marketing Tools, an online application for managing marketing campaigns, eNewsletters, landing pages and event registrations. This service relies heavily on the ability to deliver email messages to our clients’ potential customers in a responsible and efficient way.
I’ve written a set of functions that use PHP’s built-in fsockopen(), fputs() and fread() functions to send an email message properly using an SMTP (Simple Mail Transfer Protocol) server. I use the word “properly” because the built-in mail() function is very unreliable and it doesn’t include many appropriate email headers by default.
This tutorial is composed of two files: functions.php, which houses the three main functions and index.php which serves as a test page.
Contents of the functions.php file:
<?php
/* Pushes the specified value to an smtp connection. */
function jPushSMTP($oConnection, $sValue) {
fputs($oConnection, $sValue . "\r\n");
$sResponse = fread($oConnection, 1024);
return $sResponse;
}
/* Sends a message via the smtp service. */
function jSendMessageViaSMTP($a) {
// The boundary used for message headers..
$sBoundary = "Boundary-" . date("U");
// The headers for this message..
$sHeaders = "Date: " . date("r") . "\n";
$sHeaders .= "To: " . $a['ToAddress'] . "\n";
$sHeaders .= "From: " . $a['FromName'] . " <" . $a['FromAddress'] . ">\n";
$sHeaders .= "Reply-To: " . $a['ReplyAddress'] . "\n";
$sHeaders .= "Return-Path: " . $a['FromName'] . "\n"; // This may not be required..
$sHeaders .= "Subject: " . $a['Subject'] . "\n";
$sHeaders .= "X-Mailer: END[SEVEN] Mail Delivery Service\n";
$sHeaders .= "X-Priority: 3\n";
$sHeaders .= "X-Unsubscribe: <http://www.yourdomain.com/unsubscribe>\n";
$sHeaders .= "MIME-Version: 1.0\n";
$sHeaders .= "Content-Type: multipart/alternative; boundary=\"" . $sBoundary . "\"\n\n";
// The text-only version of the message..
$sHeaders .= "--" . $sBoundary . "\n";
$sHeaders .= "Content-Type: text/plain; charset=\"iso-8859-1\"\n";
$sHeaders .= "Content-Transfer-Encoding: 8bit\n\n";
$sHeaders .= $a['MessageTextOnly'] . "\n\n";
// The html version of the message..
$sHeaders .= "--" . $sBoundary . "\n";
$sHeaders .= "Content-Type: text/html; charset=\"iso-8859-1\"\n";
$sHeaders .= "Content-Transfer-Encoding: 8bit\n\n";
$sHeaders .= $a['MessageHTML'] . "\n\n";
// Close the boundary..
$sHeaders .= "--" . $sBoundary . "--\n";
// Connect to the server..
$oConnection = fsockopen($a['Server'], $a['Port'], $iErrorNum, $sErrorDescription, $a['Timeout']);
$sResponse = fread($oConnection, 1024);
$aLog[] = $sResponse;
if (!empty($oConnection)) {
$aLog[] = jPushSMTP($oConnection, "EHLO " . $a['EHLO']);
$aLog[] = jPushSMTP($oConnection, "AUTH LOGIN");
$aLog[] = jPushSMTP($oConnection, base64_encode($a['Username']));
$aLog[] = jPushSMTP($oConnection, base64_encode($a['Password']));
$aLog[] = jPushSMTP($oConnection, "MAIL FROM: <" . $a['FromAddress'] . ">");
$aLog[] = jPushSMTP($oConnection, "RCPT TO: " . $a['ToName'] . " <" . $a['ToAddress'] . ">");
$aLog[] = jPushSMTP($oConnection, "DATA");
$aLog[] = jPushSMTP($oConnection, $sHeaders);
$aLog[] = jPushSMTP($oConnection, ".\n");
$aLog[] = jPushSMTP($oConnection, "NOOP");
$aLog[] = jPushSMTP($oConnection, "NOOP");
$aLog[] = jPushSMTP($oConnection, "NOOP");
$aLog[] = jPushSMTP($oConnection, "NOOP");
$aLog[] = jPushSMTP($oConnection, "NOOP");
return $aLog;
} else {
return false;
}
}
/* Returns the default smtp values. */
function jDefaultValues() {
$a = array();
$a['FromAddress'] = "";
$a['FromName'] = "";
$a['EHLO'] = "localhost";
$a['MessageHTML'] = "No message has been specified.";
$a['MessageTextOnly'] = "No message has been specified.";
$a['Password'] = "";
$a['Port'] = "25";
$a['ReplyAddress'] = "";
$a['Server'] = "localhost";
$a['Subject'] = "No Subject";
$a['Timeout'] = 120;
$a['ToAddress'] = "";
$a['ToName'] = "";
$a['Username'] = "";
return $a;
}
?>
There are three functions in this file. They are:
- jDefaultValues() – Returns an array with the required values.
- jSendMessageViaSMTP() – Puts it all together.
- jPushSMTP() – Pushes each line of SMTP communication.
And the contents of the index.php file:
<?php
require_once("./functions.php");
$a = jDefaultValues();
$a['FromAddress'] = "sample@sample.com";
$a['FromName'] = "Sample McSample";
$a['EHLO'] = "localhost";
$a['MessageHTML'] = "This is an <b>html</b> message.";
$a['MessageTextOnly'] = "This is a text-only version of the message.";
$a['Password'] = "[YOUR_SMTP_PASSWORD]";
$a['Port'] = "25";
$a['ReplyAddress'] = "sample@sample.com";
$a['Server'] = "localhost";
$a['Subject'] = "I can send messages using SMTP!";
$a['Timeout'] = 120;
$a['ToAddress'] = "sample@sample.com";
$a['ToName'] = "Sample McSample";
$a['Username'] = "[YOUR_SMTP_USERNAME]";
if (!jSendMessageViaSMTP($a)) {
print('Your message could not be sent at this time. :(');
} else {
print('Your message has been sent!');
}
?>
This code has been slightly modified from the version that we use at our office, but it serves nearly the same purpose. (Our code allows attachments, which is a little more tricky). This script is very easy to implement and begin using right out of the box.
Click here to download the source files.
Continue Reading...
Posted on August 04, 2009 by Jimmy K. in Tutorials
Have you ever seen an AddThis™ button? Apparently, it is the “#1 bookmarking and sharing service” and I’m not going to lie. I see them everywhere. It’s actually a very good idea. But what if you don’t want 50+ icons on your site? Or what if JavaScript is disabled on your visitors computer? Or you don’t want to affiliate with some of those services? You can just do it yourself!
Basically, each online service such as Technorati, Digg and del.icio.us (these are just a few examples) allow users to share content passed through a simple URL. I’m going to share just the ones that I use on this blog:
<a href="http://technorati.com/faves?add=[URL]" title="Technorati" target="_blank"><img src="./icons/technorati.png" alt="Technorati" class="shareIcon" /></a>
<a href="http://twitter.com/home?status=[TITLE]%20%2D%20[URL]" title="Twitter" target="_blank"><img src="./icons/twitter.png" alt="Twitter" class="shareIcon" /></a>
<a href="http://www.facebook.com/sharer.php?u=[URL]&t=[TITLE]" title="Facebook" target="_blank"><img src="./icons/facebook.png" alt="Facebook" class="shareIcon" /></a>
<a href="http://www.myspace.com/Modules/PostTo/Pages/?u=[URL]&t=[TITLE]" title="MySpace" target="_blank"><img src="./icons/myspace.png" alt="MySpace" class="shareIcon" /></a>
<a href="http://del.icio.us/post?url=[URL]&title=[TITLE]" title="Del.icio.us" target="_blank"><img src="./icons/delicious.png" alt="Del.icio.us" class="shareIcon" /></a>
<a href="http://www.stumbleupon.com/submit/?url=[URL]" title="StumbleUpon" target="_blank"><img src="./icons/stumbleupon.png" alt="StumbleUpon" class="shareIcon" /></a>
<a href="http://digg.com/submit?phase=2&url=[URL]" title="Digg" target="_blank"><img src="./icons/digg.png" alt="Digg" class="shareIcon" /></a>
<a href="http://www.diigo.com/post?url=[URL]&title=[TITLE]" title="diigo" target="_blank"><img src="./icons/diigo.png" alt="diigo" class="shareIcon" /></a>
<a href="https://favorites.live.com/quickadd.aspx?marklet=1&mkt=en-us&url=[URL]&title=[TITLE]&top=1" title="Windows Live" target="_blank"><img src="./icons/windows.png" alt="Windows Live" class="shareIcon" /></a>
Just paste this code into your website, upload the icons supplied with this tutorial, swap the [URL] and [TITLE] tags with your own values and you’re done! Just remember that the [URL] and [TITLE] tags must be replaced with URL-encoded values. This can be achieved easily using PHP’s built-in urlencode() function.
A full list of services, icons and URLs can be found at Xillent Studios (which I modeled this tutorial after). Click here to download the source files.
Continue Reading...
Posted on July 29, 2009 by Jimmy K. in Tutorials
Have you noticed the two webcams located in the upper-right corner of this site? Those webcams are being monitored and uploaded using an Adobe AIR application, stored in a MySQL database and controlled with a PHP backend. I’m going to show you the bare bones approach to getting an image from your webcam onto your website.
First, you are going to need to create a SWF file in Adobe Flash and place the following code on the main timeline. It is known to be bad practice to place code on the main timeline, so if you’re comfortable with classes, please feel free to create a class for it.
Update: You’re also going to need to download the adobe.images package from Adobe because this tutorial utilizes the JPEGEncoder class.
import flash.display.BitmapData;
import flash.events.Event;
import flash.events.IOErrorEvent;
import flash.media.Camera;
import flash.media.Video;
import flash.net.URLRequest;
import flash.net.URLRequestMethod;
import flash.net.URLLoader;
import flash.net.URLVariables;
import flash.utils.ByteArray;
import flash.utils.setTimeout;
import com.adobe.images.JPGEncoder;
var UPLOAD_TIMEOUT:uint = 2000;
var aBitmapByteArray:ByteArray;
var iUploadTimeout:uint;
var oCamera:Camera;
var oJPGEncoder:JPGEncoder;
var oVideo:Video;
jInitCamera();
/* Initializes the camera. */
function jInitCamera() {
try {
this.oCamera = Camera.getCamera();
this.oCamera.setMode(640, 480, 15);
this.oCamera.setQuality(0, 100);
this.oVideo = new Video(640, 480);
this.oVideo.attachCamera(this.oCamera);
this.addChild(this.oVideo);
this.oJPGEncoder = new JPGEncoder(50);
this.iUploadTimeout = setTimeout(jUploadSnapshot, UPLOAD_TIMEOUT);
trace("Camera has been initialized.");
} catch (oException:*) {
trace("Unable to initialize camera.");
}
}
/* Uploads a snapshot to our web server. */
function jUploadSnapshot() {
// Create a bitmap data object to hold our snapshot..
var oBitmapData:BitmapData = new BitmapData(640, 480, false, 0x000000);
oBitmapData.draw(this.oVideo);
// Encode the bitmap data, free the memory..
this.aBitmapByteArray = oJPGEncoder.encode(oBitmapData);
oBitmapData.dispose(); oBitmapData = null;
// Create a url request to send the bitmap data..
var oURLRequest:URLRequest = new URLRequest("http://www.yourwebsite.com/upload.php");
oURLRequest.method = URLRequestMethod.POST;
oURLRequest.data = aBitmapByteArray;
// Create a url loader to perform the request..
var oURLLoader:URLLoader = new URLLoader();
oURLLoader.addEventListener(Event.COMPLETE, eUploadComplete, false, 0, true);
oURLLoader.addEventListener(IOErrorEvent.IO_ERROR, eUploadFailed, false, 0, true);
oURLLoader.load(oURLRequest);
}
/* Triggered when the upload completes. */
function eUploadComplete(oEvent1:Event) {
this.iUploadTimeout = setTimeout(jUploadSnapshot, UPLOAD_TIMEOUT);
trace("Snapshot has been uploaded.");
}
/* Triggered when the upload fails. */
function eUploadFailed(oEvent1:IOErrorEvent) {
this.iUploadTimeout = setTimeout(jUploadSnapshot, UPLOAD_TIMEOUT);
trace("Error: Unable to upload snapshot.");
}
Basically, this code initializes the default Camera on your computer, attaches it to a Video object and adds the Video object to the stage. At set intervals (in this case, every two seconds), the code draws the Video object’s bitmap data, converts the bitmap data to a byte array using the JPGEncoder class and uploads it as raw POST data to the “upload.php” file located on your web server.
What do we do with the raw POST data when it’s received by “uploader.php”? Well, we’re going to need to save the POST data as an image. This was actually the most overly-complicated part of the whole process when I was looking for help online. It’s amazing how simple it actually was:
<?php
// Save the fullsize image..
$oHandle = fopen("./fullsize.jpg", "w+");
fwrite($oHandle, file_get_contents("php://input"));
fclose($oHandle);
// Create the thumbnail image..
$oSource = imagecreatefromjpeg("./fullsize.jpg");
$oThumbnail = imagecreatetruecolor(120, 90);
imagecopyresampled($oThumbnail, $oSource, 0, 0, 0, 0, 120, 90, 640, 480);
imagejpeg($oThumbnail, "./thumb.jpg");
// Free the memory..
imagedestroy($oThumbnail);
imagedestroy($oSource);
?>
The above code simply takes the raw POST input and saves it to a file using the fopen(), file_get_contents(), fwrite() and fclose() functions. Raw POST data is available to PHP using the “php://input” protocol. I assume it’s sort of like using file_get_contents() with a “http://” protocol, only.. for PHP-related things. I’m not entirely sure how it works, but it does.
Anyway, after we save the fullsize image, we’re going to scale it down and save a thumbnail. This will help reduce server bandwidth consumption.
As you can see, this tutorial won’t create the exact implementation that I have on my website, but I leave that to your imagination and willingness to create something on your own. I hope this tutorial helps point you in the right direction and also, if you do use the concepts included in this tutorial, please let me know. I would be very interested in seeing another person’s take on it.
Click here to download the source files.
Continue Reading...
|