picture viewer

This is my own version of a picture archive and view web interface. On the corresponding server the pictures are stored in folders for year, month and day. There is also the possibility to create specific albums with pictures as well as storing pictures in a folder to reprint/copy.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
<?php ############# HEAD  ############################
echo "<!DOCTYPE html>\n";
echo "<html>\n<head>\n <meta charset='utf-8'><meta name='viewport' content='width=device-width, initial-scale=1.0'>\n";
############# style sheets ########################
echo "<link rel='stylesheet' type='text/css' href='stylesheet.css'>";
echo "<title>PictureViewer</title>\n</head>\n<body>\n\n";
echo "<header><h1>My Thoughts</h1><h4>sniplets worth to be remebered</h4></header>\n";
############# Configuration ##########################
$PHP_SELF = htmlspecialchars($_SERVER['PHP_SELF']); # use one file only which will be reload with new parameters all the time
$pathes = array("pictures" => "BackupFromMobile",
                "reprint" => "BackupFromMobile/reprint",
                "albums" => "BackupFromMobile/albums");
$thumb_params = array("width" => 300, "height" => 300, "row" => 5, "big" => 500);# thumbnail parameters
$folder_to_hide = array("pictures", "icons", "thumbnails", "bin");# some folders should not be showed normally
$file_extensions = array( "image" => array(".jpg", ".jpeg", ".png", ".gif"),
                          "audio" => array(".mp3", ".ogg", ".wav"),
                          "ebook" => array(".epub", ".pdf", ".rtx"),
                          "video" => array(".avi", ".3gp", ".flv"));# allowed extensions for files
$rotation_select_box="<option selected value='none'>none</option>
        <option value='0'>0&deg;</option>
        <option value='90'>+90&deg;</option>
        <option value='180'>+180&deg;</option>
        <option value='270'>-90&deg;</option>";# select box for image rotation in 90 degree grade
####### clear html variables from malicious code
function clean_html($variable){
    return trim(htmlspecialchars($variable));
}
###### debug output of POSTå
function debug_output(){
    echo "<pre><br><h1>Hier kommt der schamass!</h1>";
    print_r($_POST);
    echo "</pre>"; return ;
}
############# create thumbnails in subfolder ######
function check_thumbnail($path, $filename){
    global $thumb_params;
    if (!file_exists($path."thumbnails")){#create thumbnail folder
        if (!mkdir($path."thumbnails")) die ("Unable to create folder (".$path."thumbnails)!");
    }
    $thumb = new Imagick(realpath($path."/".$filename));# Imagick needs absolute path for reference
    $orientation = $thumb -> getimageorientation();# check for image orientation
    # check if rotation was selected
    if (!empty($orientation)){
        switch ($orientation){# rotate image to get it upright
            case imagick::ORIENTATION_BOTTOMRIGHT:
                $thumb->rotateimage("#000000", 180);
                break;
            case imagick::ORIENTATION_RIGHTTOP:
                $thumb->rotateimage("#000000", 90);
                break;
            case imagick::ORIENTATION_LEFTBOTTOM:
                $thumb->rotateimage("#000000", -90);
                break;
            case imagick::ORIENTATION_UNDEFINED:
                $thumb->rotateimage("#000000", 90);
                break;
        }
        $thumb->setImageOrientation(imagick::ORIENTATION_TOPLEFT);# set exif data
    }# resize image but keep ratio
    $thumb->setResourceLimit( Imagick::RESOURCETYPE_MEMORY, 2 );
    $thumb->thumbnailImage($thumb_params["width"], $thumb_params["height"], true);
    $thumb->writeImage(realpath($path)."/thumbnails/".$filename);
    return ; }
############# show side navigation #######################
function explore_directories($current_path, $target_path, $expert_mode){
    global $file_extensions, $folder_to_hide;
    echo "<ul class='navigation'>\n";
    foreach (scandir($current_path, 0) as $element){
        if (substr($element, 0, 1) != "." && !in_array($element, $folder_to_hide)){
            if (is_file($current_path."/".$element)){
                echo "<input type='hidden' name='elements[]' value='".$current_path."/".$element."'>";
                foreach ($file_extensions as $key => $value){# extensions are grouped in multidimensional array
                    if (in_array(strtolower(strrchr($element, ".")), $file_extensions[$key])){# only some file extensions will be shown
                        echo "<li class='actual_entry'><label><img src='icons/file.png'>";
                        echo "<input class='hidden' type='submit' name='folder[".$key."]' value='".$current_path."/".$element."'>".$element."</label></li>\n";
                    }
                }
            }
            else { #subfolder
                echo "<li class='navigation'><label><img src='icons/dir.png'>";
                echo "<input class='hidden' type='submit' name='folder[folder]' value='".$current_path."/".$element."/test'>".$element."</label></li>\n";
            }
            if (strncmp($current_path."/".$element, $target_path, strlen($current_path."/".$element)) == 0){
                explore_directories($current_path."/".$element, $target_path, $expert_mode);
            }
        } elseif ($element == "reprint" && $expert_mode == "normal"){# show reprint folder contents if in expert mode
            echo "<li class='navigation'><label><img src='icons/dir.png'>";
            echo "<input class='hidden' type='submit' name='folder[folder]' value='".$current_path."/".$element."/test'>".$element."</label></li>\n";
        }
    }
    echo "</ul>\n";
    return ; }
############ show thumbnails #############################
function show_thumbnails($path, $number_of_rows, $expert_mode){
    global $file_extensions,$rotation_select_box, $pathes;
    $i=0;
    foreach (scandir($path) as $file){# iterate over complete directory contents
        if (substr($file,0,1) != "." && in_array(strtolower(strrchr($file, ".")), $file_extensions["image"])){# only allowed extension will be shown
            $file = htmlspecialchars($file); $i++;# clean filename
            if (!file_exists($path."/thumbnails/".$file)){
                check_thumbnail($path."/", $file);
            }
            echo "<div class='gallery'><label><input class='hidden' type='submit' name='folder[image]' value='".$path."/".$file."'>";
            echo "<img src='".$path."/thumbnails/".$file."' alt='".$file."'></label>\n";
            if ($expert_mode == "normal"){# show checkbox for reprint
                if (strncmp($path, $pathes['reprint'], strlen($pathes['reprint'])) == 0 ) {
                    echo "<p class='delete'><input type='checkbox' name='delete".$i."' value='".$path."/".$file."'> delete from reprint list </p>\n";
                }
                else {
                    echo "<p class='reprint'><input type='checkbox' name='reprint".$i."' value='".$path."/".$file."'> reprint <span> rotate <select name='rotate".$i."'>";
                    echo $rotation_select_box."</select></span><input type='hidden' name='rotation".$i."' value='".$path."/".$file."'></p>\n";# we need the filename beside the rotation value
                    if (strncmp($path, $pathes['albums'], strlen($pathes['albums'])) == 0)
                        echo "<p class='delete'><input type='checkbox' name='delete".$i."' value='".$path."/".$file."'> delete from album </p>\n";
                    else
                        echo "<p class='album'><input type='checkbox' name='album".$i."' value='".$path."/".$file."'> add to album choosen above</p>\n";
                }
            }
            echo "</div>\n";
        }
    }
    return ;}
############# rotate pictures from list in given direction ##############
function rotatepictures($rotation, $files){
    global $thumb_params; $i=0;
    $path = dirname($files[0]);
    foreach ($files as $value) {
        $thumb = new Imagick(realpath($value));# Imagick needs absolute path for reference
        switch ($rotation[$i]){# rotate image to get it upright
            case "0";
                $thumb->rotateimage("#000000", 0);
                break;
            case "90";
                $thumb->rotateimage("#000000", 90);
                break;
            case "180":
                $thumb->rotateimage("#000000", 180);
                break;
            case "270":
                $thumb->rotateimage("#000000", -90);
                break;
        }
        $thumb->setImageOrientation(imagick::ORIENTATION_TOPLEFT);# set exif data
        $thumb->setResourceLimit( Imagick::RESOURCETYPE_MEMORY, 2 );# resize image but keep ratio
        $thumb->thumbnailImage($thumb_params["width"], $thumb_params["height"], true);
        $thumb->writeImage(realpath($path)."/thumbnails/".basename($value));
        $i++; # take a counter with us to get desired orientation
    }
    return "done";}
############# copy pics for reprint ###################
function copypictures($files, $folder){
    if (!file_exists($folder)){
        if (!mkdir($folder)) die("Could not create folder:".$folder);
    }
    foreach ($files as $value) {
        if (!copy($value, $folder."/".basename($value) ))
                die("Could not copy file".$value." to ".$folder."/".basename($value));
        }
    return "done";}
############# delete pictures from album ##############
function delpictures($files){
    foreach ($files as $value) {
        if (!unlink($value))
            die("Could not delete file".$value);
    }
    return "done";}
######################################################################
############################## MAIN ##################################
######################################################################
echo "<body><form method='POST' action='$PHP_SELF'>\n";# page header with headline and table headers
$filelist=array(); $albumlist=array();$dellist=array();$rotatelist=array();$rotationnamelist=array();# list of files for reprint
foreach (array_diff_key($_POST, array("change" => "", "action" => "", "folder" => "", "album" => "")) as $key => $value){
    if (substr($key, 0, 7) == "reprint")# files for reprint are numbered as reprint1..9
        array_push($filelist, $value);# generate array list of files to reprint
    elseif (substr($key, 0, 5) == "album")# files for album are numbered as album1..9
        array_push($albumlist, $value);# generate array list of files for actual album
    elseif (substr($key, 0, 6) == "delete")# files to delete from album
        array_push($dellist, $value);
    elseif (substr($key, 0, 6) == "rotate" && $_POST[$key] != "none"){# files to rotate
        array_push($rotatelist, $value);# store value for rotation
        $index_for_rotation="rotation".substr($key, 6);
        array_push($rotationnamelist, $_POST[$index_for_rotation]);# get image name to rotate
    }
}
# get default values for action, target folder and expert view mode
# $key = last action choosen, e.g. play video, show pictures
# $target_folder = the last folder that was opened
# $expert_mode = status of expert view
if (isset($_POST['actual_action']) && $_POST['actual_action'] != "")
    $key = clean_html($_POST['actual_action']);
else
    $key = "folder";# default action is showing pictures in folder
if (isset($_POST['folder']) && $_POST['folder'] != ""){
    foreach ($_POST[folder] as $key => $value)# generate target folder variable from POST
        $target_path = clean_html(dirname($value));# if a new folder icon was clicked update target folder
    $key = clean_html(array_keys($_POST['folder'])[0]);$value = clean_html($_POST['folder'][$key]);
}elseif (isset($_POST['actual_folder']) && $_POST['actual_folder'] != ""){
    $target_path = clean_html($_POST['actual_folder']);$value = clean_html($_POST['actual_contents']);
} else
    $target_path = $pathes['pictures'];
# check the actual status of expert view and toggle if requested by user button press
if (isset($_POST['change']) && $_POST['change'] == "expert")# button is pressed, so we need to toggle
    $expert_mode = "normal";# change value as user triggered the button to change
elseif (isset($_POST['change']) && $_POST['change'] == "normal")
    $expert_mode = "expert";# keep the old stage if set
elseif (isset($_POST['expert_mode']) && $_POST['expert_mode'] == "normal")
    $expert_mode = "normal";
else
    $expert_mode = "expert";
echo "<input type='hidden' name='expert_mode' value='".$expert_mode."'><input type='hidden' name='actual_folder' value='".$target_path."'>";
echo "<input type='hidden' name='actual_action' value='".$key."'><input type='hidden' name='actual_contents' value='".$value."'>";
############## show navigation on top ###########################################
echo "<div class='navi'><input type='submit' name='change' value='".$expert_mode."'>";
# manage access to albums in special folder
if ($expert_mode == "normal"){# select album from list if in expert mode
    echo "<select name='album'>\n<option value='new'>create new entry</option>\n";
    foreach ( glob($pathes['albums']."/*", GLOB_ONLYDIR) as $directory){
        echo "<option ";
        if (isset($_POST['album']) && $_POST['album'] == $directory)
            echo " selected ";
            echo "value='".$directory."'>".basename($directory)."</option>\n";
    }
    echo "</select>\n<input type='submit' name='action' value='action'>\n";
}
if (isset($_POST['action'])){# action button pressed
    echo "<span class='response'>";
    if (isset($_POST['new_album']) && !empty($_POST['new_album'])){
        if (!file_exists($pathes['albums']."/".$_POST['new_album']))
            if (!mkdir($pathes['albums']."/".$_POST['new_album'])) die("Could not create folder:".$_POST['new_album']);
    }
    else {
        if (isset($_POST['album']) && $_POST['album'] == "new"){
            echo "Create new album: <input type='text' size='20' name='new_album'>\n";
        }
        elseif (!empty($albumlist))# copy pictures to album
            echo copypictures($albumlist, $_POST['album']);
        if (!empty($filelist)) # copy pictures for reprint
            echo copypictures($filelist, $pathes['reprint']);
        if (!empty($dellist)) # delete entries from album
            echo delpictures($dellist);
        if (!empty($rotatelist))# rotate pictures in given direction
            echo rotatepictures($rotatelist, $rotationnamelist);
}
    echo "</span>\n";
}
explore_directories($pathes['pictures'], $target_path, $expert_mode);# show the navigation menue
echo "</div>\n";
############### page content to the right ##################################
echo "<section class='contents'>";
switch ($key){
    case "audio":
        echo "<".$key." controls height='240' width='320'>\n<source src='".$value."' type='".$key."/".strtolower(substr(strrchr($value, "."),1))."'>\n";
        echo "No support for file: ".$value." in your Browser!</".$key.">\n";
        break;
    case "video":
        echo "<".$key." controls height='240' width='320'>\n<source src='".$value."' type='".$key."/".strtolower(substr(strrchr($value, "."),1))."'>\n";
        echo "No support for file: ".$value." in your Browser!</".$key.">\n";
        break;
    case "ebook":
        echo "<br>Read ebook: ".$value."<br>";
        break;
    case "image":
        echo "<div class='gallery'>\n";
        if (isset($_POST['elements']) && $_POST['elements'] != "") {
            $number_of_pictures = count($_POST['elements'])-1;# index is running from 0 up
            for ($i=0; $i<=$number_of_pictures; $i++){# iterate over complete image list
                if ($_POST['elements'][$i] == $value){ # find the number of the current image in list
                    if ($i == 0) $last = $_POST['elements'][$number_of_pictures];# we are at position 0 already
                    else $last = $_POST['elements'][$i-1];
                    if ($i == $number_of_pictures) $next = $_POST['elements'][0];# we are at the end already
                    else $next = $_POST['elements'][$i+1];
                    echo "<div class='arrow-left'><button type='submit' name='folder[image]' value='".$last."'>";
                    echo "<img src='icons/transparent.png' style='border:none;'></button></div>";
                    echo "<a href='".$value."'> <img src='".$value."' width='".$thumb_params["big"]."' alt='".$value."'></a>";
                    echo "<div class='arrow-right'><button type='submit' name='folder[image]' value='".$next."'>";
                    echo "<img src='icons/transparent.png' style='border:none;'></button></div>";
                    break;
                }
            }
        }
        if ($expert_mode == "normal"){# show checkbox for reprint
            if (explode("/", $value)[0] == $pathes['reprint']) {
                echo "<p class='delete'><input type='checkbox' name='delete".$i."' value='".$value."'> delete from reprint list </p>\n";
            }
            else {
                echo "<p class='reprint'><input type='checkbox' name='reprint".$i."' value='".$value."'> reprint <span> rotate <select name='rotate".$i."'>";
                echo $rotation_select_box."</select></span><input type='hidden' name='rotation".$i."' value='".$value."'></p>\n";# we need the filename beside the rotation value
                if (explode("/", $value)[0] == $pathes['albums'])
                    echo "<p class='delete'><input type='checkbox' name='delete".$i."' value='".$value."'> delete from album </p>\n";
                else
                    echo "<p class='album'><input type='checkbox' name='album".$i."' value='".$value."'> add to album choosen above</p>\n";
            }
        }
        echo "</div>";
        break;
    case "folder":
        show_thumbnails($target_path, $thumb_params['row'], $expert_mode);# show thumbs
        break;
    default:
        echo "<br>File type not supported!<br>";
        break;
}
echo "</section>\n";
############# cleanup and end ########################################     
debug_output();
echo "</form>\n<footer id='footer'>My personal page hosted on my own server &copy; olkn</footer></body></HTML>\n";
########### END ###################################?>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
@CHARSET "ISO-8859-1";
body {
    background-color: #2C2C29;
    font-family:"Times New Roman", Times, serif;
    font-size: 13px;
    color: white;
}
.arrow-right {
    position: absolute;
    width: 20%;
    height: 100%;
    right: -50px;
    top: 0;
}
.arrow-left {
    position: absolute;
    width: 20%;
    height: 100%;
    left: -50px;
    top: 0;
}
.arrow-left:hover {
    background: transparent url(icons/arrow-left.png) no-repeat left center;
}
.arrow-right:hover {
    background: transparent url(icons/arrow-right.png) no-repeat right center;
}
.hidden {
    display: none;
}
.response {
    padding: 0 0 0 50px;
}
.navigation {/* navigation divs are nested on the left */
    padding: 0px 0px 0px 12px;
    text-shadow: 4px 3px 0 #444444;
}
ul {
    list-style-type: none;
    padding: 0px 20px 0px 0px;
}
li {
    padding: 0px 0px 0px 12px;
}
.navi { /* show text shadow */
    float: left;
    text-shadow: 4px 3px 0 #444444;
}
a { /* some stylings for links */
    text-decoration:none;
}
a:link {
    color: dimgray;
}
a:visited {
    color: darkgray;
}
a:hover {
    color: royalblue;
}
a:active {
    color: silver;
}
p.reprint { /* caption for reprint */
    background: teal;
    margin: 5px;
    text-align: left;
}
p.reprint span {
    float:right;
    padding: 0 5px 0 0;
}
p.album { /* caption for add to album */
    background: royalblue;
    margin: 5px;
    text-align: left;
}
p.delete { /* caption for pic delete */
    background: darkred;
    margin: 5px;
    text-align: left;
}
.gallery { /* show nice white border for pics */
    position: relative;
    display: inline-block;
    padding: 5px 5px 20px 5px;
    margin: 20px;
    background: white;
}
.gallery img {
    margin:2px;
    border:1px solid #000000;
    height:auto;
}
.gallery img:hover { /* blurr image when mouse is over */
    opacity:0.7;
    filter:alpha(opacity=70);
}
img.arrow {
    border: none;
    margin: 100% 0;
}
button {
    height: 100%;
    width: 130px;
    background: transparent;
    border: none;
}
footer { /* footer in new line */
    clear: left;
}

Leave a Reply