'),array('<','>'),file_get_contents($script)); print('
'.$phpcode.'
'); die; } // set the file to use, or prompt if none is given if (isset($input['pic'])) { $fileurl = $input['pic']; $photo = new FotonotesPlugin($fileurl); $xml = $photo->readXML(); } else { $d = dir($rootpath.$imgpath); $imglist = ''; while (false !== ($entry = $d->read())) { if (preg_match('/jpg$/i',$entry)) { $imglist .= "{$entry}
\n"; } } $thisbody = <<start again | php source | project home

{$imglist}

This script allows you to create annotations for images on the web. Enter the url of an image you want to annotate, (changes to remote files can't be saved, so you can only make one note at a time) or just try one of the local files listed above. Any notes added to the local fies can be saved on the server, so multiple notes can be saved on each picture.

EOD; pageout($thisbody, '', 'enter picture url'); die; } // set some other things. if the image is large, shrink it down by half and // keep this as $sizemult for later $filename = substr(strrchr($fileurl, "/"), 1); if (!$filename) { $filename = $fileurl; } $imagepath = substr($LOCALPATH,0,strrpos($LOCALPATH,'/')+1) . $filename; $size = getImageSize($rootpath.$fileurl); $realsize = $size; $sizemult = 1; // while (!($size[0] <= 600 && $size[1] <= 480)) { while (($size[0] * $size[1] > 640*480)) { $size[0] = $size[0]/2; $size[1] = $size[1]/2; $sizemult = $sizemult * 2; }; $size[0] = round($size[0]); $size[1] = round($size[1]); if (isset($input['pos1'])) { $mark1 = array(substr($input['pos1'],0,2), substr($input['pos1'],2)); } if (isset($input['pos2'])) { $mark2 = array(substr($input['pos2'],0,2), substr($input['pos2'],2)); } if (isset($input['text'])) { $notetext = nl2br(htmlspecialchars(trim($input['text']))); } // depending on what data has been passed, get the next information $grid = ''; $xoff = ($size[0]%$blocksize)/2; $yoff = ($size[1]%$blocksize)/2; if (isset($mark1) && isset($mark2)) { $left = min($mark1[0], $mark2[0])*$blocksize + $xoff; $top = min($mark1[1], $mark2[1])*$blocksize + $yoff; $width = (max($mark1[0], $mark2[0]) + 1)*$blocksize - $left + $xoff - 4; $height = (max($mark1[1], $mark2[1]) + 1)*$blocksize - $top + $yoff - 4; $boxcss = "#box0 { left: {$left}px; top: {$top}px; width: {$width}px; height: {$height}px; }"; $noteinfo = array(time(),$notetext, array($left*$sizemult,$top*$sizemult,($left+$width)*$sizemult,($top+$height)*$sizemult)); $timestamp = gmdate("Y-m-d\TH:i:s\Z", time()); $noteblock = array(array($fileurl,$timestamp,$filename),$noteinfo); $grid = "
"; $top = $height + 2; $left = max(-$left, min(0,($width-200)/2)); if ($width < 200) $width = 200; $notecss = "left: {$left}px; top: {$top}px; width: {$width}px;"; $grid .= "\n
\n

{$notetext}

\n
\n"; $grid .= "
"; $addxml = makexml($noteblock); preg_match_all("#/([0-9]*)@#Umsi", $xml, $ids); rsort($ids[1]); if (isset($ids[1][0])) { $id_number = $ids[1][0] + 1; } else { $id_number = 1; } $id = preg_replace("#([^/]*\.jpg)#Umsi", "$id_number@$1", $imagepath); $addxml = preg_replace("#.*#Umsi", "", $addxml); $addxml = preg_replace("#.*#Umsi", "", $addxml); $addxml = preg_replace("#.*#Umsi", "", $addxml); $addxml = preg_replace("##Umsi", "$id$timestamp$timestamp$timestamp", $addxml); if ($xml == '') { $xml = $addxml; } else { $xml = preg_replace("##Umsi", "$addxml", $xml); } } elseif (isset($input['action']) && ($input['action'] == 'add')) { for ($j = 0; $j*$blocksize <= $size[1]-$blocksize; $j += 1) { for ($i = 0; $i*$blocksize <= $size[0]-$blocksize; $i += 1) { $xystr = str_pad($i,2,'0',STR_PAD_LEFT).str_pad($j,2,'0',STR_PAD_LEFT); $col = ''; if (isset($input['pos1']) && $xystr == $input['pos1']) $col = ' red'; if (isset($input['pos2']) && $xystr == $input['pos2']) $col = ' red'; $tile = "{$xystr}"; if (isset($mark1)) $data = "?action=add&pic={$fileurl}&pos1={$input['pos1']}&pos2={$xystr}"; else $data = "?action=add&pic={$fileurl}&pos1={$xystr}"; $tile = "{$tile}"; $grid .= "\n{$tile}"; } } } if (isset($input['pic']) && (isset($input['action']) && $input['action'] == 'write')) { $photo->writeXML($xml); } elseif (isset($input['pic']) && isset($input['action']) && $input['action'] == 'delete') { $xml = ''; $photo->writeXML(''); } if (isset($input['text']) || (!isset($input['action']) || $input['action'] != 'add')) { $boxstate = << EOD; $grid = str_replace("
\n

\n
", $form, $grid); $form = ''; } else if (isset($mark1) && isset($mark2) && isset($input['text']) && (!isset($input['action']) || ($input['action'] != 'write'))) { $safexml = str_replace(array('<','>'),array('<','>'),$xml); $gridcode = str_replace(array('<','>'),array('<','>'),$grid); $form = << EOD; } else { // $safexml = str_replace(array('<','>'),array('<','>'),$xml); // $form = "
{$safexml}
"; } $guide = array("You can add an annotation to this picture. If there are annotations, you can delete all notes from this image.","Wait for the image to finish loading and a yellow border to appear. Click on a square to mark the first corner of the area you want to annotate. If the image is very large, it will have been reduced a bit. Also, outlines for existing annotations, if any, will be visible.", "Wait for the yellow border to appear again. The red square indicates the box you just selected. Click on the opposite corner of area you want to mark, or click on the red box again to mark an area only one square large.","Enter the text that will appear under the marked box.","Hover your cursor over the image to see the section that has been marked, and then hover over the marked section to read your comments. If this is a local image, you can save this note into the fotonotes xml in the jpeg by clicking 'write' below.","Changes have been saved to {$filename}."); if (isset($input['action']) && (($input['action'] == 'write') || $input['action'] == 'delete')) { $step = 5; } else { if (isset($mark1)) { if (isset($mark2)) { if (isset($input['text'])) { $step = 4; } else { $step = 3; } } else { $step = 2; } } else { if (isset($input['action']) && ($input['action'] == 'add')) { $step = 1; } else { $step = 0; } } } $htmlmap = map_xml($xml); $thisbody = <<start again | php source | project home

{$guide[$step]}

{$alt} $htmlmap $grid
$form EOD; pageout($thisbody, $thiscss, $thistitle); /// end of main code function makexml($noteblock) { $xmlout = "{$noteblock[0][1]}"; $xmlout .= "{$noteblock[1][1]}"; $xmlout .= ""; $xmlout .= "{$noteblock[1][2][0]},{$noteblock[1][2][1]},{$noteblock[1][2][2]},{$noteblock[1][2][3]}"; $xmlout .= ""; return $xmlout; } // build html for fotonotes xml already in the jpeg, if any function map_xml($xml) { global $sizemult; $html = ''; if ($xml) { // if (preg_match("#.*#",$xml,$entries)) { $entries = explode('',$xml); if (sizeof($entries) > 1) { for ($e = 1; $e < sizeof($entries); $e++) { $name = "note".$e; preg_match("#.*#",$entries[$e],$boxset); $box = split(',',substr($boxset[0],16,strlen($boxset[0])-33)); $xpos = round($box[0] / $sizemult); $ypos = round($box[1] / $sizemult); $width = round(($box[2] - $box[0]) / $sizemult); $height = round(($box[3] - $box[1]) / $sizemult); $ntop = $height + 2; $nleft = max(-$xpos, min(0,($width-200)/2)); if ($width < 200) $nwidth = 200; else $nwidth = $width; preg_match ("#.*#",$entries[$e],$cmatch); $content = substr($cmatch[0],9,strlen($cmatch[0])-19); $html .= "

{$content}

"; } } } return $html; } function pageout($body, $morecss, $title) { $page = << $title $body EOD; print($page); } /* this comes directly from Marc Rohlfing's fotonoter plugin */ class FotonotesPlugin { function FotonotesPlugin($filename) { $this->ISTHeaderNumber = 8; $this->image = $filename; } function readXML() { $xml = $this->readJPEGHeaders(); return $xml; } function writeXML($newxml) { global $timestamp, $imagepath, $filename, $LOCALPATH, $ADD, $MODIFY, $DELETE; $newtitle = ''; if (! preg_match("#<\?xml#Umsi", $newxml)) { $newtitle = basename($filename); $header = ''; $header .= ''; // $header .= 'Copyright (c) 2004, Greg Elin'; $header .= "$imagepath"; $header .= "$timestamp"; $header .= "$newtitle"; $header .= ''; $xml = $header . $newxml . ""; } else { $entries = explode("", $newxml); $entries[0] = preg_replace("#.*#Umsi", "$timestamp", $entries[0]); if ($newtitle <> '') { $entries[0] = preg_replace("#.*#Umsi", "$newtitle", $entries[0]); } $newxml = implode("", $entries); $xml = $newxml; } $xml = preg_replace("#.*#", "", $xml); $this->writeJPEGHeaders($xml); } function writeJPEGHeaders($text) { global $rootpath; $thisimage = $rootpath.$this->image; $newImage = ''; $imageIn = fopen($thisimage, "rb"); while ( ($char = fgetc( $imageIn)) > -1) { $charValue = hexdec(bin2hex($char)); if ( $charValue == 0xff ) { $char2 = fgetc( $imageIn ); if ($char2 < 0) { break; } $charValue2 = hexdec(bin2hex($char2)); if ($charValue2 == (0xe0 + $this->ISTHeaderNumber)) { $length = hexdec(bin2hex( fgetc($imageIn) . fgetc($imageIn) )); if ($length < 2) { $length = 2; } fread($imageIn,$length-2); } elseif ($charValue2 > 0xe0 && $charValue2 < (0xe0 + $this->ISTHeaderNumber)) { $lenA = fgetc($imageIn); $lenB = fgetc($imageIn); $newImage .= $char . $char2 . $lenA . $lenB; $length = hexdec(bin2hex( $lenA . $lenB )); if ($length < 2) { $length = 2; } $newImage .= fread($imageIn,$length-2); } else { if ( ($charValue2 < 0xe0 && $charValue2 != 0xd8) || $charValue2 > (0xe0 + $this->ISTHeaderNumber)) { if (strlen($text) > 0) { $length = str_pad(dechex(strlen($text) + 2),4,"0",STR_PAD_LEFT); $newImage .= pack("H*","FFe" . $this->ISTHeaderNumber . $length) . $text; } $newImage .= $char; $newImage .= $char2; break; } $newImage .= $char; $newImage .= $char2; } } else { $newImage .= $char; } } $newImage .= @fread($imageIn, @filesize($thisimage)); fclose($imageIn); if (! $this->imageOut = @fopen($thisimage,'wb')) { die("success=Error!\n\nCouldn't add annotation because \"" . $thisimage . "\" isn't writable!"); } fwrite($this->imageOut, $newImage); fclose($this->imageOut); } function readJPEGHeaders () { global $rootpath; $imageIn = fopen($rootpath.$this->image, "rb"); $this->headers[0] = 1; while ( ($char = fgetc( $imageIn)) > -1) { $charValue = hexdec(bin2hex($char)); if ( $charValue == 0xff) { $char2 = fgetc( $imageIn ); $charValue2 = hexdec(bin2hex($char2)); if ( $charValue2 > 0xe0 ) { $length = hexdec(bin2hex( fgetc($imageIn) . fgetc($imageIn) )); if (($charValue2 - 0xe0) == $this->ISTHeaderNumber) { $this->headers[ $charValue2 - 0xe0 ] = fread($imageIn,$length-2); fclose($imageIn); return $this->headers[ $charValue2 - 0xe0 ]; } } } } } function wikify($source) { $wiki = preg_replace("/\\$/Umsi", "$", $source); // external links with linktext {link:linktext|URL} $wiki = preg_replace('#{link:(.+)\|(http://[0-9a-zA-Z\.\#/~\-_%=\?&,]*)}#Ums', "$1", $wiki); // external links without linktext {link:URL} $wiki = preg_replace('#{link:(http://[0-9a-zA-Z\.\#/~\-_%=\?&,]*)}#Ums', "$1", $wiki); // email address {mailto:email} $wiki = preg_replace('#{mailto:([0-9a-zA-Z\.\#/~\-_%=\?&,@]*)}#Ums', "$1", $wiki); // image with thumbnail size {image:path|size} $wiki = preg_replace('#{image:([0-9a-zA-Z\.\#~\-_%=?/:]*)\|([0-9]*)}#Ums', "", $wiki); // image without thumbnail size {image:path} $wiki = preg_replace('#{image:([0-9a-zA-Z\.\#~\-_%=?/:]*)}#Ums', "", $wiki); return $wiki; } } ?>