Floor Wall and Roof Framing Members Song Lyrics Tutorial

Floor Wall and Roof Framing Members Song Lyrics Tutorial

Floor Wall and Roof Framing Members Song Lyrics Tutorial

What do Carpentry and Octopus Anatomy have in common? Anyone, anyone?

Yes, Ringo?

Yes, perhaps they both live in a Yellow Submarine? Or the Octopus’s Garden needs a new lattice? But, no, we invite other takers … Anyone, anyone?

Yes, Paul … you have a vision coming on … ?

2026 … yes …
World Cup … yes …
Winner will be … yes …



A…










 

 

Okay, that’s it! No more! Not even “finding an arrowed diagram for Octopus Anatomy that functioned like the one we used for our Carpentry web application” … though that’s remarkably prescient. No, it’s that … yes, Katherine and Richard … you’re right there … Songs, Lyrics, Music!

And so, further to yesterday’s Octopus Anatomy YouTube Tutorial, we’re adding access to the great Lyrics.com because, let’s face it, songs have been written for a lot of life’s ideas and thoughts in both …

  • floor_wall_roof_framing_members‘s changed code Carpentry Gamealso below

    function check(oa) {
    var dorandd=false, dolyricsmatch=false;
    //alert(document.getElementById('ui').width + ' ... ' + document.getElementById('ui').style.top + ' ... ' + document.getElementById('ui').style.left);
    var rectarr=[-1,-1,-1,-1,-1,-1,-1,-1,-1,-1];
    var words=oa.getAttribute("data-title").replace(",","").replace("(","").replace(")","").toLowerCase().split('_');
    var minx=-1, miny=-1, maxx=-1, maxy=-1, jj=0;
    var carray=oa.coords.split(',');
    if (carray.length > 4) {
    carray.push(carray[0]);
    carray.push(carray[1]);
    }
    var considered=' ... (' + carray.length + ') ';
    for (var ii=0; ii<carray.length; ii++) {
    jj = eval(eval(ii - eval(ii % 2)) / 2);
    considered+=' =' + jj + '= ';
    if (carray.length == 4) {
    if (ii == 0) {
    minx=eval(carray[ii]);
    maxx=eval(carray[ii]);
    } else if (ii == 1) {
    miny=eval(carray[ii]);
    maxy=eval(carray[ii]);
    } else if (ii == 2) {
    if (eval(carray[ii]) < minx) minx=eval(carray[ii]);
    if (eval(carray[ii]) > maxx) maxx=eval(carray[ii]);
    } else {
    if (eval(carray[ii]) < miny) miny=eval(carray[ii]);
    if (eval(carray[ii]) > maxy) maxy=eval(carray[ii]);
    }
    } else if (eval(ii % 2) == 0 && (jj == 0 || jj == 1 || jj == eval(-1 + eval(carray.length / 2)) || jj == eval(-2 + eval(carray.length / 2)) || jj == eval(-3 + eval(carray.length / 2)))) {
    if (ii == 0) {
    considered+='' + carray[ii] + ',' + carray[eval(1 + ii)];
    minx=eval(carray[ii]);
    maxx=eval(carray[ii]);
    miny=eval(carray[eval(1 + ii)]);
    maxy=eval(carray[eval(1 + ii)]);
    } else {
    considered+=',' + carray[ii] + ',' + carray[eval(1 + ii)];
    if (eval(carray[ii]) < minx) minx=eval(carray[ii]);
    if (eval(carray[ii]) > maxx) maxx=eval(carray[ii]);
    if (eval(carray[eval(1 + ii)]) < miny) miny=eval(carray[eval(1 + ii)]);
    if (eval(carray[eval(1 + ii)]) > maxy) maxy=eval(carray[eval(1 + ii)]);
    }
    }
    }
    if (minx < 75) {
    maxx=75;
    } else if (minx < 460) {
    minx=460;
    }
    if (maxx > eval(0 + document.getElementById('ui').width)) maxx = eval(0 + document.getElementById('ui').width);
    if (maxy > eval(0 + document.getElementById('ui').height)) maxy = eval(0 + document.getElementById('ui').height);
    //if (carray.length > 4) {
    // alert(carray + ' ... ' + minx + ',' + miny + ',' + ',' + maxx + ',' + maxy + considered);
    //}
    //if (oa.title.indexOf('rimmer') != -1) alert(oa.title + ' ... ' + "<div style=\"border:1px solid red;position:absolute;z-index:9;background-repeat:no-repeat;background:URL('floor_wall_roof_framing_members.jpg');background-position:-" + minx + "px -" + miny + "px;left:" + minx + "px;top:" + miny + "px;width:" + eval(maxx - minx) + "px;height:" + eval(maxy - miny) + "px;display:block;\"></div>");
    var ans=prompt("What did you point at? One blank character is the answer to give up and reveal answer, while two will offer YouTube based research material regarding the answer as well, three also does a Song Lyrics search. Suffix your answer with a space to do this research, two spaces for song lyrics, anyway, as well.", "");
    goes++;
    var prevscore=score;
    if (ans != null) {
    if (ans.indexOf(' ') == 0 && ans.trim() == '') {
    dolyricsmatch=true;
    dorandd=true;
    ans=' ';
    } else
    if (ans.indexOf(' ') == 0 && ans.trim() == '') {
    dorandd=true;
    ans=' ';
    } else if (('!' + ans + '~').replace(/\ \ \~$/g,'') != ('!' + ans + '~') && ans.trim() != '') {
    dolyricsmatch=true;
    dorandd=true;
    ans=ans.trim();

    } else if (('!' + ans + '~').replace(/\ \~$/g,'') != ('!' + ans + '~') && ans.trim() != '') {
    dorandd=true;
    ans=ans.trim();
    }
    var bwords=ans.replace(",","").replace("(","").replace(")","").toLowerCase().split(' ');
    for (var kk=0; kk<bwords.length; kk++) {
    if (bwords[kk] != "") {
    for (var mm=0; mm<words.length; mm++) {
    if (words[mm] == bwords[kk]) score++;
    }
    }
    }
    }
    if (prevscore != score || ans == " ") {
    document.getElementById('overlays').innerHTML+="<div style=\"position:absolute;z-index:9;background-repeat:no-repeat;background:URL('floor_wall_roof_framing_members.jpg');background-position:-" + minx + "px -" + miny + "px;left:" + eval(0 + minx) + "px;top:" + eval(6 + miny) + "px;width:" + eval(maxx - minx) + "px;height:" + eval(maxy - miny) + "px;display:block;\"></div>";
    if (window.self != window.parent) {
    document.getElementById('score').innerHTML='Score: ' + score + '/' + goes + " ... <br>" + oa.getAttribute("data-title").replace(/_/g,' ');
    } else {
    document.getElementById('score').innerHTML='Score: ' + score + '/' + goes + " ... " + oa.getAttribute("data-title").replace(/_/g,' ');
    }
    } else {
    document.getElementById('score').innerHTML='Score: ' + score + '/' + goes;
    }

    if (dorandd) {
    tost=fromst.replace('Djibouti%2C%20Djibouti', encodeURIComponent('carpentry ' + oa.getAttribute("data-title").replace(/_/g,' ')));
    document.getElementById('ifkar').src=ifkar.replace(fromst, tost);
    document.getElementById('ifkar').style.display='block';
    }
    if (dolyricsmatch) {
    if (lwo) {
    if (!lwo.closed) {
    lwo.close();
    lwo=null;
    }
    }
    lwo=window.open('//www.lyrics.com/lyrics/' + encodeURIComponent(oa.getAttribute("data-title").replace(/_/g,' ').toLowerCase()), '_blank', 'top=0,left=' + eval(-490 + screen.width) + ',width=490,height=520');
    }

    }
  • octopus.html‘s changed code Octopus Anatomy Game as way below


Previous relevant Octopus Anatomy YouTube Tutorial is shown below.

Octopus Anatomy YouTube Tutorial

Octopus Anatomy YouTube Tutorial

Today’s work, onto that of Octopus Anatomy Primer Tutorial is a story revolving around …

  • research … related to …
  • audio/visual learning techniques …
  • HTML iframe interfacing … to …
  • YouTube videos … via …
  • YouTube API

… as a methodology to “drill down” into subject matter whose scope is initially too big for a learner to know where to start, perhaps


function check(oa) {
var dorandd=false;
//alert(document.getElementById('ui').width + ' ... ' + document.getElementById('ui').style.top + ' ... ' + document.getElementById('ui').style.left);
var rectarr=[-1,-1,-1,-1,-1,-1,-1,-1,-1,-1];
var words=oa.getAttribute("data-title").replace(",","").replace("(","").replace(")","").toLowerCase().split('_');
var minx=-1, miny=-1, maxx=-1, maxy=-1, jj=0;
var carray=oa.coords.split(',');
if (carray.length > 4) {
carray.push(carray[0]);
carray.push(carray[1]);
}
var considered=' ... (' + carray.length + ') ';
for (var ii=0; ii<carray.length; ii++) {
jj = eval(eval(ii - eval(ii % 2)) / 2);
considered+=' =' + jj + '= ';
if (carray.length == 4) {
if (ii == 0) {
minx=eval(carray[ii]);
maxx=eval(carray[ii]);
} else if (ii == 1) {
miny=eval(carray[ii]);
maxy=eval(carray[ii]);
} else if (ii == 2) {
if (eval(carray[ii]) < minx) minx=eval(carray[ii]);
if (eval(carray[ii]) > maxx) maxx=eval(carray[ii]);
} else {
if (eval(carray[ii]) < miny) miny=eval(carray[ii]);
if (eval(carray[ii]) > maxy) maxy=eval(carray[ii]);
}
} else if (eval(ii % 2) == 0 && (jj == 0 || jj == 1 || jj == eval(-1 + eval(carray.length / 2)) || jj == eval(-2 + eval(carray.length / 2)) || jj == eval(-3 + eval(carray.length / 2)))) {
if (ii == 0) {
considered+='' + carray[ii] + ',' + carray[eval(1 + ii)];
minx=eval(carray[ii]);
maxx=eval(carray[ii]);
miny=eval(carray[eval(1 + ii)]);
maxy=eval(carray[eval(1 + ii)]);
} else {
considered+=',' + carray[ii] + ',' + carray[eval(1 + ii)];
if (eval(carray[ii]) < minx) minx=eval(carray[ii]);
if (eval(carray[ii]) > maxx) maxx=eval(carray[ii]);
if (eval(carray[eval(1 + ii)]) < miny) miny=eval(carray[eval(1 + ii)]);
if (eval(carray[eval(1 + ii)]) > maxy) maxy=eval(carray[eval(1 + ii)]);
}
}
//alert('ii=' + ii + ' ' + oa.outerHTML + ' ... ' + maxx + ' - ' + minx + ' = ' + eval(maxx - minx));
}
// if (minx < 75) {
// maxx=75;
// } else if (minx < 460) {
// minx=460;
// }
if (maxx > eval(0 + document.getElementById('ui').width)) { maxx = eval(0 + document.getElementById('ui').width); }
if (maxy > eval(0 + document.getElementById('ui').height)) { maxy = eval(0 + document.getElementById('ui').height); }
//if (carray.length > 4) {
// alert(carray + ' ... ' + minx + ',' + miny + ',' + ',' + maxx + ',' + maxy + considered);
//}
//if (oa.title.indexOf('rimmer') != -1) alert(oa.title + ' ... ' + "<div style=\"border:1px solid red;position:absolute;z-index:9;background-repeat:no-repeat;background:URL('floor_wall_roof_framing_members.jpg');background-position:-" + minx + "px -" + miny + "px;left:" + minx + "px;top:" + miny + "px;width:" + eval(maxx - minx) + "px;height:" + eval(maxy - miny) + "px;display:block;\"></div>");
var ans=prompt("What did you point at? One blank character is the answer to give up and reveal answer, while two will offer YouTube based research material regarding the answer as well. Suffix your answer with a space to do this research, anyway, as well.", "");
goes++;
var prevscore=score;
if (ans != null) {
if (ans.indexOf(' ') == 0 && ans.trim() == '') {
dorandd=true;
ans=' ';
} else if (('!' + ans + '~').replace(/\ \~$/g,'') != ('!' + ans + '~') && ans.trim() != '') {
dorandd=true;
ans=ans.trim();
}

var bwords=ans.replace(",","").replace("(","").replace(")","").toLowerCase().split(' ');
for (var kk=0; kk<bwords.length; kk++) {
if (bwords[kk] != "") {
for (var mm=0; mm<words.length; mm++) {
if (words[mm] == bwords[kk]) score++;
}
}
}
}
if (prevscore != score || ans == " ") {
document.getElementById('overlays').innerHTML+="<div style=\"position:absolute;z-index:9;background-repeat:no-repeat;background:URL('oct_opus.png');background-position:-" + minx + "px -" + miny + "px;left:" + eval(0 + minx) + "px;top:" + eval(6 + miny) + "px;width:" + eval(maxx - minx) + "px;height:" + eval(maxy - miny) + "px;display:block;\"></div>";
document.getElementById('score').innerHTML='Score: ' + score + '/' + goes + " ... " + oa.getAttribute("data-title").replace(/_/g,' ');
//if (ans == " ") { alert(oa.getAttribute("data-title").replace(/_/g,' ')); }
} else {
if (window.self != window.parent) {
document.getElementById('score').innerHTML='Score: ' + score + '/' + goes + " ... <br>" + oa.getAttribute("data-title").replace(/_/g,' ');
} else {
document.getElementById('score').innerHTML='Score: ' + score + '/' + goes;
}
//if (prevscore == score) { alert(oa.getAttribute("data-title").replace(/_/g,' ')); }
}

if (dorandd) {
tost=fromst.replace('Djibouti%2C%20Djibouti', encodeURIComponent('octopus ' + oa.getAttribute("data-title").replace(/_/g,' ')));
document.getElementById('ifkar').src=ifkar.replace(fromst, tost);
document.getElementById('ifkar').style.display='block';
}

}

… in octopus.html‘s changed code Octopus Anatomy game …


Previous relevant Octopus Anatomy Primer Tutorial is shown below.

Octopus Anatomy Primer Tutorial

Octopus Anatomy Primer Tutorial

What do Carpentry and Octopus Anatomy have in common? Many hands make light fittings get a bevelled edge? No, for us, finding an arrowed diagram for Octopus Anatomy that functioned like the one we used for our Carpentry web application of Floor Wall and Roof Framing Members Primer Tutorial below.

So much so, we kept the same Javascript logic and bits of the HTML other than the …

  • img element image … doh! … and …
  • underlying (image) map element … created in that similar (great, stupendous) mobilefish (thanks) method as for the Carpentry web application

To get from today’s octopus.html‘s changed code then we …

  1. started with the Carpentry HTML and Javascript code as a basis …
  2. surfing the net found interesting octopus image via this Google image search finding this applicable image (from “Methodologies for studying finfish and shellfish biology” (ISBN: 978-93-82263-03-6) by Dineshbabu Ap), thanks, that we scanned and copied (and which we later change) into an image file on this MacBook Pro that was uploaded to …
  3. visited mobilefish to create the new image (img element) and associated map element …
  4. replaced the old Carpentry img and map with the new Octopus ones, pointing the img element src property at the correct image … that image now …
  5. opened octopus image in Gimp and Gaussian Blurred out the octopus labels via …
    • Tools -> Selection Tools -> Rectangle Select
    • Filters -> Blur -> Gaussian Blur… Horizontal: 14.0px Vertical: 14.0px
  6. (unit) tested code, and realized we’d forgotten to …
  7. within the new octopus img and map code replace all ” title=” for ” data-title=” (to hide answers from the user) and ” href=” for ” data-href=” to stop navigation resetting the score

… to arrive at where we are at with today’s live run. We hope you try it, and learn a bit about Octopus Anatomy should that be your thing!


Previous relevant Floor Wall and Roof Framing Members Primer Tutorial is shown below.

Floor Wall and Roof Framing Members Primer Tutorial

Floor Wall and Roof Framing Members Primer Tutorial

We all learn differently, but personally, I find it easier to learn things of a certain ilk and things that are new to me, when the study material is augmented by pictures in the form of a diagram or photograph or video, perhaps. I know very little about carpentry, and get lost in conversations talking about “joists” and “bearers”, so, today, we’ve purloined the great mobilefish image map (of HTML area elements) creator website and this very useful webpage (the source of the great diagram … thanks) to piece together today’s “click and learn” web application.

We use some overlay techniques with today’s game where the user tries to identify diagram labels Gaussian Blurred out (via GIMP) while a non-Gaussian-Blurred-out image is used (in an overlayed way) as the background (via background-position definitions) for HTML divs …

  • position:absolute; left:[derivedViaMinAreaXCoords]px; top:[derivedViaMinAreaYCoords]px; width:[derivedViaMaxMinDiffAreaXCoords]px; height:[derivedViaMaxMinDiffAreaYCoords]px;
  • z-index:9;
  • background:URL([non-Gaussian-Blurred-out_image]); background-position:-[derivedViaMinAreaXCoords]px -[derivedViaMinAreaYCoords]px;
  • data attributes (eg. data-title) hide answers from the user to avoid making it all too easy, and internalize navigation (eg. data-href)

revealed as above when the user gives up (via a space answer) or answers some words correctly in the Javascript prompt window used to prompt the user for “carpentry” terminology word matches, the score incrementing for each correct word match.

Now hope you don’t go around “nogging” in public with your newfound knowledge trying out today’s live run test of your carpentry and building knowledge. It is based on HTML and CSS and Javascript you could call floor_wall_roof_framing_members.html and download, as you wish.

If this was interesting you may be interested in this too.


If this was interesting you may be interested in this too.


If this was interesting you may be interested in this too.


If this was interesting you may be interested in this too.

Posted in eLearning, Event-Driven Programming, Games, Tutorials | Tagged , , , , , , , , , , , , , , , , , | Leave a comment

Octopus Anatomy YouTube Tutorial

Octopus Anatomy YouTube Tutorial

Octopus Anatomy YouTube Tutorial

Today’s work, onto that of Octopus Anatomy Primer Tutorial is a story revolving around …

  • research … related to …
  • audio/visual learning techniques …
  • HTML iframe interfacing … to …
  • YouTube videos … via …
  • YouTube API

… as a methodology to “drill down” into subject matter whose scope is initially too big for a learner to know where to start, perhaps


function check(oa) {
var dorandd=false;
//alert(document.getElementById('ui').width + ' ... ' + document.getElementById('ui').style.top + ' ... ' + document.getElementById('ui').style.left);
var rectarr=[-1,-1,-1,-1,-1,-1,-1,-1,-1,-1];
var words=oa.getAttribute("data-title").replace(",","").replace("(","").replace(")","").toLowerCase().split('_');
var minx=-1, miny=-1, maxx=-1, maxy=-1, jj=0;
var carray=oa.coords.split(',');
if (carray.length > 4) {
carray.push(carray[0]);
carray.push(carray[1]);
}
var considered=' ... (' + carray.length + ') ';
for (var ii=0; ii<carray.length; ii++) {
jj = eval(eval(ii - eval(ii % 2)) / 2);
considered+=' =' + jj + '= ';
if (carray.length == 4) {
if (ii == 0) {
minx=eval(carray[ii]);
maxx=eval(carray[ii]);
} else if (ii == 1) {
miny=eval(carray[ii]);
maxy=eval(carray[ii]);
} else if (ii == 2) {
if (eval(carray[ii]) < minx) minx=eval(carray[ii]);
if (eval(carray[ii]) > maxx) maxx=eval(carray[ii]);
} else {
if (eval(carray[ii]) < miny) miny=eval(carray[ii]);
if (eval(carray[ii]) > maxy) maxy=eval(carray[ii]);
}
} else if (eval(ii % 2) == 0 && (jj == 0 || jj == 1 || jj == eval(-1 + eval(carray.length / 2)) || jj == eval(-2 + eval(carray.length / 2)) || jj == eval(-3 + eval(carray.length / 2)))) {
if (ii == 0) {
considered+='' + carray[ii] + ',' + carray[eval(1 + ii)];
minx=eval(carray[ii]);
maxx=eval(carray[ii]);
miny=eval(carray[eval(1 + ii)]);
maxy=eval(carray[eval(1 + ii)]);
} else {
considered+=',' + carray[ii] + ',' + carray[eval(1 + ii)];
if (eval(carray[ii]) < minx) minx=eval(carray[ii]);
if (eval(carray[ii]) > maxx) maxx=eval(carray[ii]);
if (eval(carray[eval(1 + ii)]) < miny) miny=eval(carray[eval(1 + ii)]);
if (eval(carray[eval(1 + ii)]) > maxy) maxy=eval(carray[eval(1 + ii)]);
}
}
//alert('ii=' + ii + ' ' + oa.outerHTML + ' ... ' + maxx + ' - ' + minx + ' = ' + eval(maxx - minx));
}
// if (minx < 75) {
// maxx=75;
// } else if (minx < 460) {
// minx=460;
// }
if (maxx > eval(0 + document.getElementById('ui').width)) { maxx = eval(0 + document.getElementById('ui').width); }
if (maxy > eval(0 + document.getElementById('ui').height)) { maxy = eval(0 + document.getElementById('ui').height); }
//if (carray.length > 4) {
// alert(carray + ' ... ' + minx + ',' + miny + ',' + ',' + maxx + ',' + maxy + considered);
//}
//if (oa.title.indexOf('rimmer') != -1) alert(oa.title + ' ... ' + "<div style=\"border:1px solid red;position:absolute;z-index:9;background-repeat:no-repeat;background:URL('floor_wall_roof_framing_members.jpg');background-position:-" + minx + "px -" + miny + "px;left:" + minx + "px;top:" + miny + "px;width:" + eval(maxx - minx) + "px;height:" + eval(maxy - miny) + "px;display:block;\"></div>");
var ans=prompt("What did you point at? One blank character is the answer to give up and reveal answer, while two will offer YouTube based research material regarding the answer as well. Suffix your answer with a space to do this research, anyway, as well.", "");
goes++;
var prevscore=score;
if (ans != null) {
if (ans.indexOf(' ') == 0 && ans.trim() == '') {
dorandd=true;
ans=' ';
} else if (('!' + ans + '~').replace(/\ \~$/g,'') != ('!' + ans + '~') && ans.trim() != '') {
dorandd=true;
ans=ans.trim();
}

var bwords=ans.replace(",","").replace("(","").replace(")","").toLowerCase().split(' ');
for (var kk=0; kk<bwords.length; kk++) {
if (bwords[kk] != "") {
for (var mm=0; mm<words.length; mm++) {
if (words[mm] == bwords[kk]) score++;
}
}
}
}
if (prevscore != score || ans == " ") {
document.getElementById('overlays').innerHTML+="<div style=\"position:absolute;z-index:9;background-repeat:no-repeat;background:URL('oct_opus.png');background-position:-" + minx + "px -" + miny + "px;left:" + eval(0 + minx) + "px;top:" + eval(6 + miny) + "px;width:" + eval(maxx - minx) + "px;height:" + eval(maxy - miny) + "px;display:block;\"></div>";
document.getElementById('score').innerHTML='Score: ' + score + '/' + goes + " ... " + oa.getAttribute("data-title").replace(/_/g,' ');
//if (ans == " ") { alert(oa.getAttribute("data-title").replace(/_/g,' ')); }
} else {
if (window.self != window.parent) {
document.getElementById('score').innerHTML='Score: ' + score + '/' + goes + " ... <br>" + oa.getAttribute("data-title").replace(/_/g,' ');
} else {
document.getElementById('score').innerHTML='Score: ' + score + '/' + goes;
}
//if (prevscore == score) { alert(oa.getAttribute("data-title").replace(/_/g,' ')); }
}

if (dorandd) {
tost=fromst.replace('Djibouti%2C%20Djibouti', encodeURIComponent('octopus ' + oa.getAttribute("data-title").replace(/_/g,' ')));
document.getElementById('ifkar').src=ifkar.replace(fromst, tost);
document.getElementById('ifkar').style.display='block';
}

}

… in octopus.html‘s changed code Octopus Anatomy game …


Previous relevant Octopus Anatomy Primer Tutorial is shown below.

Octopus Anatomy Primer Tutorial

Octopus Anatomy Primer Tutorial

What do Carpentry and Octopus Anatomy have in common? Many hands make light fittings get a bevelled edge? No, for us, finding an arrowed diagram for Octopus Anatomy that functioned like the one we used for our Carpentry web application of Floor Wall and Roof Framing Members Primer Tutorial below.

So much so, we kept the same Javascript logic and bits of the HTML other than the …

  • img element image … doh! … and …
  • underlying (image) map element … created in that similar (great, stupendous) mobilefish (thanks) method as for the Carpentry web application

To get from today’s octopus.html‘s changed code then we …

  1. started with the Carpentry HTML and Javascript code as a basis …
  2. surfing the net found interesting octopus image via this Google image search finding this applicable image (from “Methodologies for studying finfish and shellfish biology” (ISBN: 978-93-82263-03-6) by Dineshbabu Ap), thanks, that we scanned and copied (and which we later change) into an image file on this MacBook Pro that was uploaded to …
  3. visited mobilefish to create the new image (img element) and associated map element …
  4. replaced the old Carpentry img and map with the new Octopus ones, pointing the img element src property at the correct image … that image now …
  5. opened octopus image in Gimp and Gaussian Blurred out the octopus labels via …
    • Tools -> Selection Tools -> Rectangle Select
    • Filters -> Blur -> Gaussian Blur… Horizontal: 14.0px Vertical: 14.0px
  6. (unit) tested code, and realized we’d forgotten to …
  7. within the new octopus img and map code replace all ” title=” for ” data-title=” (to hide answers from the user) and ” href=” for ” data-href=” to stop navigation resetting the score

… to arrive at where we are at with today’s live run. We hope you try it, and learn a bit about Octopus Anatomy should that be your thing!


Previous relevant Floor Wall and Roof Framing Members Primer Tutorial is shown below.

Floor Wall and Roof Framing Members Primer Tutorial

Floor Wall and Roof Framing Members Primer Tutorial

We all learn differently, but personally, I find it easier to learn things of a certain ilk and things that are new to me, when the study material is augmented by pictures in the form of a diagram or photograph or video, perhaps. I know very little about carpentry, and get lost in conversations talking about “joists” and “bearers”, so, today, we’ve purloined the great mobilefish image map (of HTML area elements) creator website and this very useful webpage (the source of the great diagram … thanks) to piece together today’s “click and learn” web application.

We use some overlay techniques with today’s game where the user tries to identify diagram labels Gaussian Blurred out (via GIMP) while a non-Gaussian-Blurred-out image is used (in an overlayed way) as the background (via background-position definitions) for HTML divs …

  • position:absolute; left:[derivedViaMinAreaXCoords]px; top:[derivedViaMinAreaYCoords]px; width:[derivedViaMaxMinDiffAreaXCoords]px; height:[derivedViaMaxMinDiffAreaYCoords]px;
  • z-index:9;
  • background:URL([non-Gaussian-Blurred-out_image]); background-position:-[derivedViaMinAreaXCoords]px -[derivedViaMinAreaYCoords]px;
  • data attributes (eg. data-title) hide answers from the user to avoid making it all too easy, and internalize navigation (eg. data-href)

revealed as above when the user gives up (via a space answer) or answers some words correctly in the Javascript prompt window used to prompt the user for “carpentry” terminology word matches, the score incrementing for each correct word match.

Now hope you don’t go around “nogging” in public with your newfound knowledge trying out today’s live run test of your carpentry and building knowledge. It is based on HTML and CSS and Javascript you could call floor_wall_roof_framing_members.html and download, as you wish.

If this was interesting you may be interested in this too.


If this was interesting you may be interested in this too.


If this was interesting you may be interested in this too.

Posted in eLearning, Event-Driven Programming, Games, Software | Tagged , , , , , , , , , , , , , , | Leave a comment

Knockout Dice Game Emoji Tutorial

Knockout Dice Game Emoji Tutorial

Knockout Dice Game Emoji Tutorial

To our mind, the invention of emojis has been a really positive part of the online world. Maybe we’re that extra bit fond of them because it can go somewhere on the way to …

  • covering up image media deficiencies (cough, cough) with this text/image hybrid alternative where the artistry has already been done, just asking for your coding intervention to use (where our favourite emoji coding access means, (using example of “dice” here) is to …
    1. type … [search strings] emojipedia ( ie. dice emojipedia ) … into the web browser address bar …
    2. click/tap relevant Google search Emojipedia link
    3. click/tap Technical Information tab link
    4. copy the U+1F3B2 style of Codepoint presented to paste into the web browser address bar …
    5. click/tap the relevant link (our preferred being, for single entities, the FileFormat.info) link
    6. copy the relevant HTML Entity (decimal) ( ie. &#127922; ) into the buffer

    ) … ready to paste at the relevant place ( or use String.fromCodePoint(127922) … 🎲 ) of the HTML or Javascript code … as well as the emoji talents of …

  • emojis are a help with Internationalization of your web application … as well as …
  • adding colour into the webpage aesthetics look
  • adding interest into the webpage aesthetics look … and because they are that hybrid between image and text …
  • adding interest into the webpage content
  • With this in mind, we spent some time, onto yesterday’s Knockout Dice Game Checkbox Tutorial progress for that Knockout Dice Game making it …

    Knockout 👊 Dice 🎲🎲 Game

    … even there in the web browser tab’s title.

    For the first time we can remember we needed to get ahead of the curve picking a suitable CSS font-family property for all text with this work because we found that some of the dice guise emojis were really new and not found in all the font families out there, so …


    <style>
    * { font-family: 'DejaVu Sans'; }

    .xone:before { font-family: 'DejaVu Sans'; content: '\002680'; color:blue; }
    .xtwo:before { font-family: 'DejaVu Sans'; content: '\002681'; color:blue; }
    .xthree:before { font-family: 'DejaVu Sans'; content: '\002682'; color:blue; }
    .xfour:before { font-family: 'DejaVu Sans'; content: '\002683'; color:blue; }
    .xfive:before { font-family: 'DejaVu Sans'; content: '\002684'; color:blue; }
    .xsix:before { font-family: 'DejaVu Sans'; content: '\002685'; color:blue; }
    .zone:after { font-family: 'DejaVu Sans'; content: '\002680'; color:blue; }
    .ztwo:after { font-family: 'DejaVu Sans'; content: '\002681'; color:blue; }
    .zthree:after { font-family: 'DejaVu Sans'; content: '\002682'; color:blue; }
    .zfour:after { font-family: 'DejaVu Sans'; content: '\002683'; color:blue; }
    .zfive:after { font-family: 'DejaVu Sans'; content: '\002684'; color:blue; }
    .zsix:after { font-family: 'DejaVu Sans'; content: '\002685'; color:blue; }

    .kout:after { content: '\01f44A'; }

    #snum { background-color: yellow; }

    #header { background-color: #f0f0f0; }

    select { white-space:pre-wrap; border-radius: 6px; }

    button { border-radius: 12px; }

    </style>

    … solved some issues for us, here. And in researching totally CSS ways to style via content, again, we got a leave pass to not look again. CSS (style) and HTML (substance) have been separated by the W3C powers that be, for a reason, and we see that CSS selectors based on “content starts with” will never happen, though you can probably use jQuery library calls to achieve this.

    Okay, with that in mind, we abandoned a CSS only “cute” way to display die values either side of a numerical dice roll total in the header table cell which updates dynamically, instead using this Javascript …


    function diceemojis(totv, secv) {
    var hprefix='', hsuffix='', classbit='';
    var firstv=eval(totv - secv);
    if (1 == 1) {
    var sels=document.getElementsByTagName('select');
    for (var isels=0; isels<sels.length; isels++) {
    if (('' + sels[isels].value.replace(/^0/g,'')) == ('' + totv)) { classbit=' class="kout"'; }
    }
    hprefix=('' + secv).replace(/1/g, '<sup class=xone></sup>').replace(/2/g, '<sup class=xtwo></sup>').replace(/3/g, '<sup class=xthree></sup>').replace(/4/g, '<sup class=xfour></sup>').replace(/5/g, '<sup class=xfive></sup>').replace(/6/g, '<sup class=xsix></sup>')
    hsuffix=('' + firstv).replace(/1/g, '<sub class=zone></sub>').replace(/2/g, '<sub class=ztwo></sub>').replace(/3/g, '<sub class=zthree></sub>').replace(/4/g, '<sub class=zfour></sub>').replace(/5/g, '<sub class=zfive></sub>').replace(/6/g, '<sub class=zsix></sub>')
    return hprefix + '<span' + classbit + ' id="span' + rollno + '">' + totv + '</span>' + hsuffix;
    }
    return (' <span class="' + firstv + ' ' + secv + '">' + totv + '</span>').replace(/\ 1\"/g, ' zone"').replace(/\ 2\"/g, ' ztwo"').replace(/\ 3\"/g, ' zthree"').replace(/\ 4\"/g, ' zfour"').replace(/\ 5\"/g, ' zfive"').replace(/\ 6\"/g, ' zsix"').replace(/\"1\ /g, '"xone ').replace(/\"2\ /g, '"xtwo ').replace(/\"3\ /g, '"xthree ').replace(/\"4\ /g, '"xfour ').replace(/\"5\ /g, '"xfive ').replace(/\"6\ /g, '"xsix ');
    }

    … to start making this happen in the changed knockout_dice_game.html Knockout Dice Game you can also try below.


    Previous relevant Knockout Dice Game Checkbox Tutorial is shown below.

    Knockout Dice Game Checkbox Tutorial

    Knockout Dice Game Checkbox Tutorial

    Around here, we’re often moving on in a project via …

    • the changing of hardcodings into “dropdown” select elements (especially within h1 header elements) … but today, to move on, we arrange for …
    • the nested insertion of a checkbox (initially checked) within an h1 header element

    … which for the first time we can remember, we adjust “opacity aesthetics” to add a useful dynamic setting adjustment to the Knockout Dice Game created when we presented Knockout Dice Game Primer Tutorial some time ago now …


    <h1><div id=divword style=display:inline-block;>Knockout</div> Dice Game for <div id='dnum' style='display:inline-block;'><select style='display:inline-block;' onchange='fixinstone(this.value);' id='snum'><option value=2>2</option><option value=3>3</option><option value=4>4</option><option value=5>5</option><option value=6>6</option><option value=7>7</option><option value=8>8</option><option value=9>9</option></select></div> <span id=sgwta style=opacity:1.0;><input onchange="document.getElementById('sgwta').style.opacity='' + eval(1.1 - eval('' + document.getElementById('sgwta').style.opacity));" style=display:inline-block;opacity:1.0; type=checkbox id=gwta checked></input>Winner Take All</span> Players</h1>

    This “Winner Takes All” checkbox controlled mode of use defaults to being set (which is unusual for us, when we add a new form of methodology like this) because we discovered, revisiting this game, that “passivity” was, sort of, being rewarded and so we felt like we needed to add in the idea (and the concept of “No Winner” needed to be added), into the game, where it is really user participation encouraged here, to make the game interesting. Adding to that interest is that in a “Winner Takes All” mode of use, if a player can be the lone player to survive “Knockouts” they score a point for every roll of the two dice to get to this “lone winner” scenario.

    The other issue we noticed were the right hand overflows of our tabulated dropdowns when a lot of players are asked for. We started rearranging content justifications (to now be left justified) so it did not matter if we reduced the (now a better Responsive Design friendly table cell percentage) widths of those dropdowns, so as to fit more fields into the webpage …


    tg+="<td><select style=width:100%;background-color:cyan; id='gplayer" + jhow + "'><option value='06'>[6] Knockout value ...</option><option value='6'>6</option><option value='7'>7</option><option value='8'>8</option><option value='9'>9</option></select></td><td><div id='score" + jhow + "'>Score: 0/0</div></td>";

    … in the changed knockout_dice_game.html Knockout Dice Game you can also try below …


    Previous relevant Knockout Dice Game Primer Tutorial is shown below.

    Knockout Dice Game Primer Tutorial

    Knockout Dice Game Primer Tutorial

    Further to the previous Dice Guessing Game Primer Tutorial, today, we have for you another Dice Game, this time …

    • a dice game for 2 to 9 players … which you should establish, as necessary, straight up …
    • then rename any player names you don’t want to be the default Player1 up to Player9 values, again, making use of the contenteditable=”true” global HTML attribute and the HTML div element’s onchange event to achieve this
    • then in each round of competition the players choose a two dice roll value between 6 to 9 as the value they don’t want to see turn up, because if it does, they score nothing for that round of competition, else the players last not rejected when there is one or no players left, score a point in that round of competition … and …
    • the web application randomly throws the dice the necessary number of times to find winner(s) once the “Roll the Dice for Each Player” button is pressed

    We’d like to thank the very useful webpage for ideas for how (for the most part) this Knockout Dice Game design, execution and rules should go.

    And again, we’d welcome your try out of this new Knockout Dice Guessing Game, and please feel free to tell us what you think. Its HTML and Javascript and CSS underpinning its functionality can be perused by downloading the knockout_dice_game.html link.


    Previous relevant Dice Guessing Game Primer Tutorial is shown below.

    Dice Guessing Game Primer Tutorial

    Dice Guessing Game Primer Tutorial

    There are many HTML Entities based around punctuation that can add to the means by which you communicate ideas with your web applications.

    In today’s new (up to two player) Dice Game, we use some of these to represent the numbers from 1 to 6 on the faces of the dice, similar to how you may have seen this happen with dice in various games you play, or hanging from your car’s front visor perhaps?

    We’d welcome your try out of this Dice Guessing Game, and feel free to tell us what you think (or if its two of you “tell us what you think” … huh?!). Its HTML and Javascript and CSS underpinning its functionality can be perused by downloading the dice_game.html link. If you do, you’ll see the mildly interesting scoring system, that can be explained via the equation …


    [CorrectAnswerScoreIncrement] = 7 - (NumberOfPossibilitiesInFull36PossibilitiesSet)

    … allowing for the incorporation of this Javascript array initialization …


    var probabilities=[0,0,1,2,3,4,5,6,5,4,3,2,1]; // score will be 7-guessValue

    … that we were capable of working out ourselves but were reassured by the mathematics of this very useful link, thanks.

    Another game thought unique to how we do things that has been introduced today, is that a user can change the default player names, those being Player1 and Player2 via an HTML div element utilizing the contenteditable=”true” global HTML attribute to make it look readable, but be also “quietly” editable.

    You can also see this play out at WordPress 4.1.1’s Dice Guessing Game Primer Tutorial.

    If this was interesting you may be interested in this too.


    If this was interesting you may be interested in this too.


    If this was interesting you may be interested in this too.


    If this was interesting you may be interested in this too.

    Posted in eLearning, Event-Driven Programming, Games, Tutorials | Tagged , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , | Leave a comment

    Knockout Dice Game Checkbox Tutorial

    Knockout Dice Game Checkbox Tutorial

    Knockout Dice Game Checkbox Tutorial

    Around here, we’re often moving on in a project via …

    • the changing of hardcodings into “dropdown” select elements (especially within h1 header elements) … but today, to move on, we arrange for …
    • the nested insertion of a checkbox (initially checked) within an h1 header element

    … which for the first time we can remember, we adjust “opacity aesthetics” to add a useful dynamic setting adjustment to the Knockout Dice Game created when we presented Knockout Dice Game Primer Tutorial some time ago now …


    <h1><div id=divword style=display:inline-block;>Knockout</div> Dice Game for <div id='dnum' style='display:inline-block;'><select style='display:inline-block;' onchange='fixinstone(this.value);' id='snum'><option value=2>2</option><option value=3>3</option><option value=4>4</option><option value=5>5</option><option value=6>6</option><option value=7>7</option><option value=8>8</option><option value=9>9</option></select></div> <span id=sgwta style=opacity:1.0;><input onchange="document.getElementById('sgwta').style.opacity='' + eval(1.1 - eval('' + document.getElementById('sgwta').style.opacity));" style=display:inline-block;opacity:1.0; type=checkbox id=gwta checked></input>Winner Take All</span> Players</h1>

    This “Winner Takes All” checkbox controlled mode of use defaults to being set (which is unusual for us, when we add a new form of methodology like this) because we discovered, revisiting this game, that “passivity” was, sort of, being rewarded and so we felt like we needed to add in the idea (and the concept of “No Winner” needed to be added), into the game, where it is really user participation encouraged here, to make the game interesting. Adding to that interest is that in a “Winner Takes All” mode of use, if a player can be the lone player to survive “Knockouts” they score a point for every roll of the two dice to get to this “lone winner” scenario.

    The other issue we noticed were the right hand overflows of our tabulated dropdowns when a lot of players are asked for. We started rearranging content justifications (to now be left justified) so it did not matter if we reduced the (now a better Responsive Design friendly table cell percentage) widths of those dropdowns, so as to fit more fields into the webpage …


    tg+="<td><select style=width:100%;background-color:cyan; id='gplayer" + jhow + "'><option value='06'>[6] Knockout value ...</option><option value='6'>6</option><option value='7'>7</option><option value='8'>8</option><option value='9'>9</option></select></td><td><div id='score" + jhow + "'>Score: 0/0</div></td>";

    … in the changed knockout_dice_game.html Knockout Dice Game you can also try below …


    Previous relevant Knockout Dice Game Primer Tutorial is shown below.

    Knockout Dice Game Primer Tutorial

    Knockout Dice Game Primer Tutorial

    Further to the previous Dice Guessing Game Primer Tutorial, today, we have for you another Dice Game, this time …

    • a dice game for 2 to 9 players … which you should establish, as necessary, straight up …
    • then rename any player names you don’t want to be the default Player1 up to Player9 values, again, making use of the contenteditable=”true” global HTML attribute and the HTML div element’s onchange event to achieve this
    • then in each round of competition the players choose a two dice roll value between 6 to 9 as the value they don’t want to see turn up, because if it does, they score nothing for that round of competition, else the players last not rejected when there is one or no players left, score a point in that round of competition … and …
    • the web application randomly throws the dice the necessary number of times to find winner(s) once the “Roll the Dice for Each Player” button is pressed

    We’d like to thank the very useful webpage for ideas for how (for the most part) this Knockout Dice Game design, execution and rules should go.

    And again, we’d welcome your try out of this new Knockout Dice Guessing Game, and please feel free to tell us what you think. Its HTML and Javascript and CSS underpinning its functionality can be perused by downloading the knockout_dice_game.html link.


    Previous relevant Dice Guessing Game Primer Tutorial is shown below.

    Dice Guessing Game Primer Tutorial

    Dice Guessing Game Primer Tutorial

    There are many HTML Entities based around punctuation that can add to the means by which you communicate ideas with your web applications.

    In today’s new (up to two player) Dice Game, we use some of these to represent the numbers from 1 to 6 on the faces of the dice, similar to how you may have seen this happen with dice in various games you play, or hanging from your car’s front visor perhaps?

    We’d welcome your try out of this Dice Guessing Game, and feel free to tell us what you think (or if its two of you “tell us what you think” … huh?!). Its HTML and Javascript and CSS underpinning its functionality can be perused by downloading the dice_game.html link. If you do, you’ll see the mildly interesting scoring system, that can be explained via the equation …


    [CorrectAnswerScoreIncrement] = 7 - (NumberOfPossibilitiesInFull36PossibilitiesSet)

    … allowing for the incorporation of this Javascript array initialization …


    var probabilities=[0,0,1,2,3,4,5,6,5,4,3,2,1]; // score will be 7-guessValue

    … that we were capable of working out ourselves but were reassured by the mathematics of this very useful link, thanks.

    Another game thought unique to how we do things that has been introduced today, is that a user can change the default player names, those being Player1 and Player2 via an HTML div element utilizing the contenteditable=”true” global HTML attribute to make it look readable, but be also “quietly” editable.

    You can also see this play out at WordPress 4.1.1’s Dice Guessing Game Primer Tutorial.

    If this was interesting you may be interested in this too.


    If this was interesting you may be interested in this too.


    If this was interesting you may be interested in this too.

    Posted in eLearning, Event-Driven Programming, Games, Tutorials | Tagged , , , , , , , , , , , , , , , | Leave a comment

    MacBook Air macOS Sequoia Image Playground Tutorial

    MacBook Air macOS Sequoia Image Playground Tutorial

    MacBook Air macOS Sequoia Image Playground Tutorial

    One of the first “out of the box” applications to catch our eye from our Apple macOS install of macOS Sequoia talked about at MacBook Air macOS Sequoia Install Tutorial was …


    Image Playground

    … which we first opened none the wiser to this desktop image creator/editor new to us. We got creating images we’d never have been able to create, content wise, before, in a matter of minutes, and then we asked Google Is macOS Image Playground using AI and it all became clear …

    This is a taste of AI in the image creation workspace.

    So then we wondered if there was a set of rules, yet, about How to Indicate Content is Partially/Wholly AI Generated and realized that there is a way to go, yet, in this space, so that we can inform the reader that image content here contains AI generated image content, so …

    Image based content in this blog posting is AI generated.

    Okay?!

    So, what do we think about macOS Image Playground?

    We’re amazed, no two ways about it … very clever software.

    What else?

    We’ll be avoiding it in favour of pre-AI approaches until the dust settles, we’re thinking, for now, until real creatives’ work can be protected, hopefully getting someway there via some standards.

    What do you think? Is this wildly different to “Photoshopping” images/screenshots (which we are very fond of, here)? Where’s the line?


    Previous relevant MacBook Air macOS Sequoia Install Tutorial is shown below.

    MacBook Air macOS Sequoia Install Tutorial

    MacBook Air macOS Sequoia Install Tutorial

    It’s been ages since we’ve performed an Apple MacBook macOS upgrade after macOS 11 (ie. Big Sur (and then there was macOS Sonoma version 14 in the mix as we went along)) lifted our head in Calendar Location Services Integration Tutorial.

    But, today we decided to install macOS …

    Sequoia 15.3.1 after reading “the blurb”. Really, it seems, at this early stage, full of great surprises we’ll get more into over time!


    Previous relevant Calendar Location Services Integration Tutorial is shown below.

    Calendar Location Services Integration Tutorial

    Calendar Location Services Integration Tutorial

    Of all those English question words …

    • why
    • which
    • how
    • what
    • who
    • when
    • where

    … which is more apt as far as software goes? Well, and sorry to our regulars who have heard our theories so often, it goes in order of prominence …

    • where
    • when

    … then the rest … ie. the reverse order of order way above, we reckon.

    And so, being reminded on an upgrade of our macOS version to Big Sur version 11.6 the other day, opening the macOS Calendar desktop application version 11.0 (2811.5.1) (as we did earlier, with a previous version, with Calendar iCal Integration Itinerary Time Tutorial), that locations were honoured with an Apple Maps integration (should you permit Location Services to help you) along with news about Siri integration improving Calendar’s AI credentials, we were pretty much tickled pink to be combining the “when” with the “where” in the one desktop application.

    Maybe you will be too?!


    Previous relevant Calendar Location Services Integration Tutorial is shown below.

    Calendar iCal Integration Itinerary Time Tutorial

    Calendar iCal Integration Itinerary Time Tutorial

    A while back we left off our software integration of Calendar iCal Events into Google Chart Timeline Chart functionality (last visited with Calendar iCal Integration Itinerary Post Tutorial as shown below) with the quote …

    … closing the circle, for now, with our Calendar Event software integrated Timelines.

    … but want to retreat from that “finality”, because it’s been burning away within us as an annoyance, regarding this software integration. We think we can do better (with the integration). And we now think that, doing the research and development on this, that it is technically fairly easy to make that improvement, which goes …

    We want to have the Google Chart Timeline Chart date resolution to match the Calendar iCal Event resolution, which is to the nearest second, rather than to the nearest day, as it used to be for our Google Chart Timeline Charts

    … but we are going to hang back from asking for time hh24:mi:ss entries in the Google Chart Timeline Chart web application itself (when executing as the “parent” web application), because we can accept time data coming in from, say, the Itinerary web application, specifying the date and times to the nearest second (optionally). The reason for this is that to ask for the time everywhere can be offputting when there are so many Timeline scenarios where it is not really the “go” … think, “dates in history” for example.

    What is in the “innards” of the Google Chart Timeline Chart web application controlling this “date” (data) resolution? It is controlled by calls to create Javascript Date objects via Javascript Date object constructor (calls), and up to now, they have been exclusively of the form …


    var date_object = new Date(year, month, date);

    … and this set us to exploring other Javascript Date object constructors, and, as you’d expect … but is a little non-intuitive because of the “Date” object naming … well that’s my excuse, anyway … it allows for (the overload) …


    var date_object = new Date(year, month, date, hour, minute, second);

    But that is not to say that just to see that this (Javascript functionality) is so, doesn’t always make it so (for Google Chart usage). However, it just so happens, it does, in this case, because there are no problems changing these Date constructor calls as far as the software interface to the Google Charts Timeline Chart API is concerned (we unit tested to confirm) … yayyyy!!

    It does mean, though, that the code should handle either type of constructor, and this constructor is significant to our Google Chart select (onclick) event coding, as we examine these constructors from document.head.innerHTML to glean this information.

    We may, next, but not for now, extend the Google Chart Timeline Chart web application to ask for times optionally, perhaps, via the clicking of an HTML input type=checkbox element, but for now we’re happy, because a user can do any of …

    • Google Chart Timeline Chart web application execution where it is the parent web application … date resolution: day
    • Itinerary (web application) that displays into the Google Chart Timeline Chart web application … date resolution: second
    • Date and Time Timeline with Calendar iCal Events (web application) that displays into the Google Chart Timeline Chart web application … date resolution: second

    … and the last two are available as links from the first, so, we figure, the user can end up with what they were after, with all these choices of execution modes.

    And so, what timezones happen here?

    • Google Chart Timeline Chart web applications use your local date (and time)
    • Calendar iCal Event destination use your local date (and time) too … but …
    • iCal interfacing messages most easily use “Z” form, that uses GMT dates (and time)
    • Itinerary (or Date and Time Timeline with Calendar iCal Events) web application allows for times in any timezone you designate

    … and we have to map any non-local timezone usage to local time, especially with the last option above, to avoid confusion, and to make Calendar iCal Event destination application data match the content, and now, resolution, of its Google Chart Timeline Chart counterpart. Annoyance over!

    The results of this work consisted of …

    • no changes to external Javascript you could call gettopost.js … called defer=’defer’ by …
    • our PHP “Itinerary”, and now, also, “Generic Timeline with Dates and Times” code you could call itinerary.php which changed a lot, and has the “Itinerary” type of live run and has the “Generic Timeline with Dates and Times (and Calendar Events)” type of live run
    • our PHP above calls the original Google Chart Timeline Chart (with its “onclick” select event functionality) you could call timeline_chart.php which changed a little to recognize Timelines that can Involve Times (and Calendar Events) as well as the usual Dates (and if you want to try its live run … then there it went?!)

    Previous relevant Calendar iCal Integration Itinerary Post Tutorial is shown below.

    Calendar iCal Integration Itinerary Post Tutorial

    Calendar iCal Integration Itinerary Post Tutorial

    We’re improving software integration on a few fronts today, extending the existing Itinerary software from Calendar iCal Integration Itinerary Tutorial as shown below, namely …

    • realizing that the only difference between an “Itinerary” and any “Timeline Involving Dates and Times (and Calendar Events)” is the descriptive bits about airports and such things, so why not use the same code, and allow for a call a certain way, to turn that “Itinerary” code into the code for that generic “Timeline Involving Dates and Times (and Calendar Events)” … which affected …
    • the Google Chart Timeline Chart needs to allow for these new functionalities … and so it does with code in between <head> and </head> …

      setTimeout(itintobitsatend, 900);
      function itintobitsatend() {
      <?php
      if (file_exists("itinerary.php")) {
      echo "
      if (document.getElementById('bitsatend').innerHTML.indexOf('Itinerary') == -1) {
      document.getElementById('bitsatend').innerHTML+='&nbsp;<a target=_blank title=Itinerary href=http://www.rjmprogramming.com.au/PHP/TimelineChart/itinerary.php>Itinerary with Calendar Events</a>&nbsp;<a target=_blank title=Times href=http://www.rjmprogramming.com.au/PHP/TimelineChart/itinerary.php?justaddtime=y>Timeline with Dates and Times and Calendar Events</a>';
      }
      ";
      }
      ?>
      }

      … as well as …
    • our software integration improvement we did that “proof of concept” preparation about yesterday with HTML Div Overlay Jigsaw Talents Primer Tutorial that is actually the means by which we cater for large amounts of “Itinerary” or “Generic Timeline with Dates and Times” data by
      1. establishing a new external Javascript using HTML script property defer=’defer’ loaded after the local Javascript (that contains a “stub” function maybegettopost(instg, showit) { return instg; }) with two major functions … namely …
        • a page load setTimeout started function lookforjigsaw() that looks for an HTML div “jigsaw” arrangement like talked about yesterday, and if not, create the scenario, and leave the user with a 3 member array of HTML div id list for original content, iframe perhaps later overlays content, form to fire off iframe data as required content respectively, usage … and …
        • an external Javascript overloading version of function maybegettopost(instg, showit) that checks the length of the proposed get $_GET[] type parameter call (ie. using ? and & on address bar with long URLs), and if too long, convert that $_GET[] type parameter call data into $_POST[] type parameter call (remembering … doh … that the PHP (sorrrryyyy) receiver code should cater for this)
      2. change the “Itinerary” PHP web application code to, from now on, when calling another web application in a (default) $_GET[] type parameter call way, filter that call data through function maybegettopost(instg, showit) … the showit is a boolean that is true if we end up navigating to that call data “URL” (ie. we “show it”)

    Maybe you need to see the software additions and changes to see this for yourself, which consisted of …

    • new external Javascript you could call gettopost.js … called defer=’defer’ by …
    • our PHP “Itinerary”, and now, also, “Generic Timeline with Dates and Times” code you could call itinerary.php which changed a little, and now has the “Itinerary” type of live run and has the “Generic Timeline with Dates and Times (and Calendar Events)” type of live run
    • our PHP above calls the original Google Chart Timeline Chart (with its “onclick” select event functionality) you could call timeline_chart.php which changed a little to recognize Timelines that can Involve Times (and Calendar Events) as well as the usual Dates (and if you want to try its live run … then there it was?!)

    … closing the circle, for now, with our Calendar Event software integrated Timelines. With such software integration, break complex integrations into bits you can unit test, and don’t move on until that unit test works. On the next level of unit testing, make sure you prove that previous unit tests still work.


    Previous relevant Calendar iCal Integration Itinerary Tutorial is shown below.

    Calendar iCal Integration Itinerary Tutorial

    Calendar iCal Integration Itinerary Tutorial

    After the recent Calendar iCal Integration Timeline Tutorial you may have associated a Timeline with a Calendar event, even when the End Time of that event is not a defined concept, but what about a software integration, again with a Google Chart, but this time with …


    Google Chart Timeline Chart

    … “shaped” into a web application suitable to enter Itinerary information and then be able to associate these Timeline Start and End Events with iCal Calendar Starts and Ends to events, created …

    • interactively, using the user’s default iCal application … and/or (in the case of “mobile” we should say “but rather”) via …
    • email via PHP mail function

    ? This “Itinerary” concept has a huge amount of synergy with Calendar events, especially as a reminder service to people going on the trip (of the Itinerary) and/or to those affected by their absence, and so we found it a concrete type of web application to “start” out on. Yes, and there’s more! Tomorrow’s blog posting, you’ll have trouble believing, will have a connection, as a “proof of concept”, of where we go next with this project. So, after tomorrow’s explanation, we’ll probably see you back hereabouts in two days.

    But, in the meantime, for starters, try the PHP source code of itinerary.php and its live run to see what we are getting at here. If you try it, you’ll see that the Emoji Overlay sizing is determined on a integration “parent” subject by integration “parent” subject basis.


    Previous relevant Calendar iCal Integration Timeline Tutorial is shown below.

    Calendar iCal Integration Timeline Tutorial

    Calendar iCal Integration Timeline Tutorial

    After the recent Calendar iCal Integration WordPress Tutorial we found another integration candidate for our Calendar Event (creating) (component) “tool” web application that could be used in a variety of ways by other web applications. The second cab off the rank for this we decided should be (this) …


    Google Chart Annotated Timeline Chart

    … which should come as no surprise of a candidate for Calendar integration.

    So a few things have come together for this work, those being …

    • Calendar iCal Integration WordPress Tutorial got us into an integration with PHP and fitting in with existing Javascript DOM issues … but only for discrete Emoji concepts … whereas …
    • Emoji Overlay Share Tutorial yesterday was a proof of concept in two ways …
      1. code to respond to click events with regard to Emoji Overlays … but it also had within the code, and we tested it behind the scenes, the way it could …
      2. work off HTML primed with the special class “emojioverlay” and primed with a Javascript DOM property that would yield Emoji discrete “characters” but with the “#” missed out … believe me, this “kludgy feeling” idea saves a lot of bother because when you go back and retrieve the innerHTML property of Emoji data you do not easily arrive back at …

        &#[codepoint];

        … and we work via our homegrown Javascript docgetclass function to be able to overlay Emojis via the usual …

        • position:absolute property
        • opacity … and though it was optional for today’s work, we also included the third often used “overlay” CSS “player” … namely …
        • z-index

        … and this Javascript function …

        function checkforclass() {
        var buildup="";
        var cfcs=docgetclass('emojioverlay','*');
        for (var ij=0; ij<cfcs.length; ij++) {
        if (cfcs[ij].innerHTML.replace(/&amp;/g,'&').indexOf(';&') != -1) {
        var emjs=cfcs[ij].innerHTML.replace(/&amp;/g,'&').split("&");
        buildup='';
        cfcs[ij].style.opacity=eval(cfcs[ij].style.opacity / eval(-1 + emjs.length));
        for (var iemjs=1; iemjs<emjs.length; iemjs++) {
        buildup+='<span style="position:absolute;top:' + cfcs[ij].style.top + ';left:' + cfcs[ij].style.left + ';font-size:' + cfcs[ij].style.fontSize + ';opacity:' + cfcs[ij].style.opacity + ';z-index:' + cfcs[ij].style.zIndex + ';">&#' + emjs[iemjs].split(';')[0] + ';</span>';
        }
        cfcs[ij].innerHTML=buildup;
        cfcs[ij].style.visibility='visible';
        }
        }
        }

      … that is the method used today to display an Emoji Overlay “character” to reflect, for a mobile application WebView scenario, of PHP mail created email usage for the Calendar Event creation functionality

    • Google Chart Annotated Timeline Flash Legacy Tutorial introduced the flexible non-flash and flash toggling functionality of the Google Chart for Timelines PHP web application we wrote called annotatedtimeline_chart.php which changed quite a lot, like “function checkforclass” above, for this Calendar Event creation integration

    Why not try a Google Chart Annotated Timeline Chart live run to see what we are getting at, and while you’re there, try turning on a Calendar Event linked to one of the Timeline Events?


    Previous relevant Calendar iCal Integration WordPress Tutorial is shown below.

    Calendar iCal Integration WordPress Tutorial

    Calendar iCal Integration WordPress Tutorial

    After yesterday’s Calendar iCal Integration Email Tutorial we hoped we had a Calendar Event (creating) (component) “tool” web application that could be used in a variety of ways by other web applications. The first cab off the rank for this we decided should be (this) …


    WordPress Blog

    … that being our TwentyTen themed local effort. One of the reasons we plumped for this is that it involves Publishing Dates and we can even get access to a Publishing Time and even a Publishing Timezone (though this last one is a “hardcoded” (piece of) knowledge, rather than it being gleaned by WordPress (data) in any way). So we had the choice of means of display of this new functionality …

    • adding to logic of the already hyperlinked Publishing Date data string
    • adding the Publishing Time as a new HTML a (hyper)link placed after the Publishing Date and linking to the Calendar functionality
    • adding relevant Emojis as new HTML a (hyper)links after the Publishing Date and linking to the Calendar functionality

    … and we plumped for the last of these thoughts with our work today, as we liked the look of 📅 ➕ 📧 (that we tried out with our proof of concept p_o_f.html) to point at …

    • Create iCal Calendar Entry
    • Create and Email iCal Calendar Entry
    • Email (only) iCal Calendar Entry

    … respectively. The “go” with the email functionalities could be that you share a tutorial link with a friend whose email you know and correspond with.

    And so it behoves us to show you (good ol’) TwentyTen header.php (the usual suspect) changes to make this happen below, for your perusal and/or interest …


    function docgetclass(inc, intag) {
    if (document.getElementsByClassName) {
    return document.getElementsByClassName(inc);
    } else {
    var ijl;
    var anarris=[];
    var huhs=document.getElementsByTagName(intag);
    for (ijl=0; ijl<huhs.length; ijl++) {
    if (huh[ijl].className.indexOf(inc) != -1) {
    anarris.push(huhs[ijl]);
    }
    }
    return anarris;
    }
    }

    function calendar_pass() {
    var thisc='', thiscc='', thist='', jiicp=0, thisdate='', thistime='', nexttime='', thishour=0, nexthour=0, thisminute='', thissecond='00', thisurl='';
    var h1cps=docgetclass('entry-title','*'); //document.getElementsByTagName('h2');
    var cps=document.getElementsByTagName('a');
    for (var iicp=0; iicp<h1cps.length; iicp++) {
    thist=h1cps[iicp].innerHTML.split(' <')[0].split('<')[0];
    thisurl='';
    if (h1cps[iicp].innerHTML.indexOf(' id="d') != -1) {
    thisurl="https://www.rjmprogramming.com.au/ITblog/" + h1cps[iicp].innerHTML.split(' id="d')[1].split('"')[0];
    }
    if (jiicp < cps.length) {
    while (jiicp < cps.length && (cps[jiicp].innerHTML.indexOf(' content="') == -1 || cps[jiicp].innerHTML.indexOf('&#') != -1)) {
    jiicp++;
    }
    if (jiicp < cps.length) {
    if (cps[jiicp].title.indexOf(':') != -1) {
    thisdate=cps[jiicp].innerHTML.split(' content="')[1].split('"')[0].replace('-','').replace('-','');
    thishour=eval(cps[jiicp].title.split(':')[0]);
    nexthour=thishour;
    if (cps[jiicp].title.indexOf(' pm') != -1 && thishour < 12) thishour+=12;
    if (thishour < 12) {
    nexthour+=12;
    } else if (nexthour < 23) {
    nexthour=23;
    }
    thisminute=cps[jiicp].title.split(':')[1].split(' ')[0];
    thistime=':' + ('0' + thishour).slice(-2) + thisminute + thissecond;
    nexttime=':' + ('0' + nexthour).slice(-2) + thisminute + thissecond;
    //alert(thist + ' ' + thisurl + ' ' + thisdate + thistime);
    //alert("http://www.rjmprogramming.com.au/PHP/ics_attachment.php?id=0&eventwords=test&title=" + encodeURIComponent(thist) + '&stage=' + encodeURIComponent(h1cps[iicp].innerHTML.split(' id="d')[1].split('"')[0]) + '&datestart=' + encodeURIComponent(thisdate + thistime) + '&dateend=' + encodeURIComponent(thisdate + thistime) + '&emode=Address&address=Address&description=Description&url=' + encodeURIComponent(thisurl));
    //window.open("http://www.rjmprogramming.com.au/PHP/ics_attachment.php?id=0&tz=" + encodeURIComponent("Australia/Perth,Australia/Perth") + "&eventwords=test&title=" + encodeURIComponent(thist) + '&stage=' + encodeURIComponent(h1cps[iicp].innerHTML.split(' id="d')[1].split('"')[0]) + '&datestart=' + encodeURIComponent(thisdate + thistime) + '&dateend=' + encodeURIComponent(thisdate + nexttime) + '&emode=AndTo&address=' + encodeURIComponent('rmetcalfe15@gmail.com') + '&description=Description&url=' + encodeURIComponent(thisurl), '_blank', 'top=45,left=55,width=600,height=600');
    thisc="http://www.rjmprogramming.com.au/PHP/ics_attachment.php?id=0&tz=" + encodeURIComponent("Australia/Perth,Australia/Perth") + "&eventwords=test&title=" + encodeURIComponent(thist) + '&stage=' + encodeURIComponent(h1cps[iicp].innerHTML.split(' id="d')[1].split('"')[0]) + '&datestart=' + encodeURIComponent(thisdate + thistime) + '&dateend=' + encodeURIComponent(thisdate + nexttime) + '&emode=To&address=emailAddress&description=Description&url=' + encodeURIComponent(thisurl);
    thiscc="http://www.rjmprogramming.com.au/PHP/ics_attachment.php?id=0&tz=" + encodeURIComponent("Australia/Perth,Australia/Perth") + "&eventwords=test&title=" + encodeURIComponent(thist) + '&stage=' + encodeURIComponent(h1cps[iicp].innerHTML.split(' id="d')[1].split('"')[0]) + '&datestart=' + encodeURIComponent(thisdate + thistime) + '&dateend=' + encodeURIComponent(thisdate + nexttime) + '&emode=Address&address=&description=Description&url=' + encodeURIComponent(thisurl);
    cps[jiicp].innerHTML+=' <a id="ce' + h1cps[iicp].innerHTML.split(' id="d')[1].split('"')[0] + '" title="Create iCal Calendar Event ' + thist + '" target=_blank href="' + "http://www.rjmprogramming.com.au/PHP/ics_attachment.php?id=0&tz=" + encodeURIComponent("Australia/Perth,Australia/Perth") + "&eventwords=test&title=" + encodeURIComponent(thist) + '&stage=' + encodeURIComponent(h1cps[iicp].innerHTML.split(' id="d')[1].split('"')[0]) + '&datestart=' + encodeURIComponent(thisdate + thistime) + '&dateend=' + encodeURIComponent(thisdate + nexttime) + '&emode=AndTo&address=' + encodeURIComponent('rmetcalfe15@gmail.com') + '&description=Description&url=' + encodeURIComponent(thisurl) + '">&#128197;</a>';
    cps[jiicp].innerHTML+=' <iframe id="ice' + h1cps[iicp].innerHTML.split(' id="d')[1].split('"')[0] + '" src="about:blank" style="display:none;width:1px;height:1px;"></iframe><a title="Email and Create iCal Calendar Event ' + thist + '" target=_blank href="#" onclick=" var emtwo=prompt(' + "'" + 'Who do we email to?' + "','fillin@email.in'); document.getElementById('ice" + h1cps[iicp].innerHTML.split(' id="d')[1].split('"')[0] + "').src='" + thisc + "'.replace(/emailAddress/g, encodeURIComponent(emtwo)); window.open('" + thiscc + "','_blank'); \">&#10133;</a>";
    cps[jiicp].innerHTML+=' <a id="ee' + h1cps[iicp].innerHTML.split(' id="d')[1].split('"')[0] + '" title="Email iCal Calendar Event ' + thist + '" target=_blank href="#" onclick=" var em=prompt(' + "'" + 'Who do we email to?' + "','fillin@email.in'); window.open('" + thisc + "'.replace(/emailAddress/g, encodeURIComponent(em)),'_blank'); \">&#128231;</a>";
    jiicp+=3;
    cps=document.getElementsByTagName('a');
    }
    }
    }
    }
    }

    </script>
    <?php
    if (isset($_GET['showtags'])) {
    echo "<link href='//www.rjmprogramming.com.au/HTMLCSS/showtags.css' rel='stylesheet' type='text/css'>";
    }
    ?>
    </head>
    <body onload=" checkonl(); setTimeout(initpostedoncc, 3000); sdescih(); widgetcon(); precc(); courseCookies(); cookie_fonts(); is_mentioned_by(); calendar_pass(); " <?php body_class(); ?>>

    We hope you try out this WordPress TwentyTen themed blog functionality introduced with this code above.


    Previous relevant Calendar iCal Integration Email Tutorial is shown below.

    Calendar iCal Integration Email Tutorial

    Calendar iCal Integration Email Tutorial

    With yesterday’s Calendar iCal Integration Timezone Tutorial‘s emphasis on timezones, we turn our attention now, thinking of our web application as a “tool” and an integrated software product, to two interrelated issues …

    1. What does the future hold as far as using this Calendar “tool” (web application)? In other words, what software and/or operating system platforms will use it and in what way.
    2. How do we respond with this Calendar “tool” web application, fitting in with the requirements implicit in what the whole gammut of software and/or operating system platforms needing its services will need.

    The most “asking” of “software and/or operating system platforms” that we can think of here is to cater for a mobile application WebView (please read here regarding Android WebView (using Eclipse or Android Studio IDEs) and iOS UIWebView (using Xcode IDE)) using the Calendar “tool” web application. Mobile platform WebViews can be programmed with Back and Forward navigation buttons, but that is not the ideal thing to rely on to get you out of a pickle that your web application may cause a mobile application WebView, if it navigates out to a place where there is no navigable return. The Back and Forward mobile application WebView buttons may work to return from a Calendar Event population event … honestly don’t know … but we’d prefer to cater for a new means by which such an “offshoot” feeling of navigation can be avoided. So in our new incarnation of the Calendar (event) web application we allow any/all of the following three modes of rjmprogramming-event.ics creation …

    1. Create iCal Calendar Entry
    2. Email (only) iCal Calendar Entry
    3. Create and Email iCal Calendar Entry

    … where the second of those above would leave you, within the web application running within a mobile application’s WebView, not moving off the webpage you are on, and thus not falling foul of any “offshoot” navigation weaknesses (to the process).

    This new emailing functionality, again only in serverside PHP (and not in clientside Javascript), is relatively easy to arrange by rearranging many of the PHP header statements and feeding that through to the PHP mail function to shoot off the email, given that the user, ahead of time, has supplied you with that filled in email address, which we also attend to today.

    Our web application has, in two separate areas of the code, made use of an HTML select element’s child option elements’ title properties to contain useful information for the web application’s workings. We’ll show you below some code to access the information stored from such an arrangement …


    <select onchange='document.getElementById("subb").value=this.options[this.selectedIndex].title;' id='emode' name='emode'><option title='Create iCal Calendar Entry' value='Address'>Address</option><option title='Email (only) iCal Calendar Entry' value='To'>Email To (only)</option><option title='Create and Email iCal Calendar Entry' value='AndTo'>Email To (as well)</option></select>

    … and you might wonder about the destination for the HTML option title property storage here? We use it to rename our HTML form’s input type=submit button that fires off the callback message. The “guises” of our one HTML input type=submit thus have a one to one correspondence with the values on that HTML select (dropdown) element, and with that list of “modes of output” we showed above. This is our approach to this today, but there are other approaches to such requirements regarding HTML form element HTML input type=submit element arrangements, and you may prefer to use multiple forms and/or multiple input type=submit buttons as we talk about with the series of blog posts finishing, so far, with HTML Multiple Form Multiple Submit Buttons Primer Tutorial.

    Actually yesterday we prepared for another eventuality down the road of usefulness for this web application, but before we tell you about that, what we’d encourage you to do yourself should you put such a Calendar (event) web application into production is, interface your data flow not with $_POST[] (nor $_GET[] … damn, gave away the secret) but we’d prefer you to have it be that data in and out, as required, is stored in a secure database of some sort, for security purposes. But back to our (not very well kept) secret, yesterday, we prepared the ground for the web application (callback functionality) to be accessible via PHP $_GET[] arguments.

    So, sorry not to have moved off “tool” (web application) work today, but it is very important to try to think of most/all eventualities you can imagine, ahead of the time when you get to the integration tasks the other way around, that is, the integration from the viewpoint of the software acting as “parent” or “co-operative peer” to your Calendar (event) “tool” web application.

    The reshaped PHP code now additionally catering for email “messaging” functionality you could call ics_attachment.php, which changed in this way, able to be run with this live run link. We hope you try out the new email functionality yourself.


    Previous relevant Calendar iCal Integration Timezone Tutorial is shown below.

    Calendar iCal Integration Timezone Tutorial

    Calendar iCal Integration Timezone Tutorial

    You might have thought with yesterday’s Calendar iCal Integration Primer Tutorial‘s emphasis on timezones we’d have …

    • had too much
    • seen too little
    • invited Goldilocks for some porridge

    … but time is quite a complex scenario on Earth, when it comes to timezones for at least two reasons, one being a functional improvement, and one being to fix a bug, that being …

    1. things like WebEx or Skype or GoTo Meeting are not tied down by geography and you may want Calendar functionality to reflect this, or you may also want it to cater for airplane departure and arrival times in various timezones around the world, and it would be best if the HTML form user entry phase catered for a user specifying a date and time not necessarily in either of their local timezone nor the GMT timezone (of the iCal “Z” property special interest) … is the functional improvement, whereas …
    2. we had a bug, leaving off from yesterday’s work with timezones whose GMT offset involved half hour differences … and yes, that happens quite often … and the bug will occur as of yesterday’s code when you come to use those PHP DateTime object add and/or sub methods where the PT[offset]H argument has an [offset] involving a decimal point, so it behoves us to update that relevant PHP code snippet for you, again, below, regarding that (and remind … forgot yesterday … that $ts variable is a user HTML form passed date and time) …

      $di="PT" . str_replace("-","",("" . $start_end_offsets[$thisi])) . "H";
      $parsed_date = DateTime::createFromFormat('Ymd:His', $ts);
      if (strpos(("" . $start_end_offsets[$thisi]), "-") !== false) {
      if (strpos($di, ".") !== false) {
      $parsed_date->sub(new DateInterval(explode(".",$di)[0] . "H"));
      $parsed_date->sub(new DateInterval("PT30M"));
      } else {
      $parsed_date->sub(new DateInterval($di));
      }
      } else {
      if (strpos($di, ".") !== false) {
      $parsed_date->add(new DateInterval(explode(".",$di)[0] . "H"));
      $parsed_date->add(new DateInterval("PT30M"));
      } else {
      $parsed_date->add(new DateInterval($di));
      }
      }
      $outts = $parsed_date->format('Ymd:His');

    Now allowing for the first idea above is not as involved as you may think, but only if you think serverside PHP, rather than think it will be easy with clientside Javascript. And what makes it a doddle, generally, are all those Open Source contributors to knowledge out there, and those great computing program language documenters out there exemplified in their brilliance with this totally useful link to the PHP timezone_identifiers_list and PHP DateTimeZone object method getOffset method links. So we allow the user to enter any of …

    • Local
    • GMT
    • Any of the half hour timezone numerical offset (indicators) from -24 to 24
    • Any of the timezone names as per those PHP methods above, with valid continental prefix names

    … to define the start and end date and time parameters to express for their Calendar iCal Event that they define. Along the way we also add in dropdowns and HTML input type=number (year) elements to help for those not so keen on keyboard entry.

    Guess you’d say we are still on the “tool” feel of the web application, but aim to move more on the “integration” front into the future.

    Here is the renewed PHP code you could call ics_attachment.php, that changed in this way, able to be run with this live run link. We hope you try it out for yourself, especially as we’ve added some Google Chart Map Chart linking of the “when” and “where” of defined timezone thinking, via the use of PHP’s DateTimeZone object method getLocation, as you can see happening with today’s tutorial picture.


    Previous relevant Calendar iCal Integration Primer Tutorial is shown below.

    Calendar iCal Integration Primer Tutorial

    Calendar iCal Integration Primer Tutorial

    Do you remember us talking about the ICS extension file when we presented WebEx Prerecording Primer Tutorial as shown below? It is an integration input to working with iCal Calendar software.

    So here we are at a “when” of life tutorial, which is always an interesting exercise in our book. And “book” could be the go for an application to use this type of functionality. When you “book” something, you’d often want to remind yourself and/or others of such an event. But for now, we are concentrating on making a “tool” type of web application that will suit future purposes.

    We’ve built a web application around the useful logic presented in this great Git repository today, writing our code in PHP, because you are dealing with header manipulation here centering around …


    header('Content-type: text/calendar; charset=utf-8');
    header('Content-Disposition: attachment; filename=rjmprogramming-event.ics');
    echo $ical;

    … where the PHP variable $ical contents has been pieced together in response to a callback from an earlier HTML form execution of the same ics_attachment.php code where the necessary details are collected off the user.

    If you try the live run you’ll probably glean that most of our concern centered around the date and time, regarding timezone use so that we …

    • in the HTML form execution we use client Javascript to glean the local timezone and local date and time to default the form appropriately … so that …
    • in the HTML form execution the user fills out Calendar Event start and end times with respect to local time and this, along with an offset to get these times back to UTC or (Greenwich Mean Time) are passed to the callback web application (which is the same web application) … so that …
    • the second callback execution constructs the iCal (for an rjmprogramming-event.ics attachment) with these UTC (or GMT) date and times in mind, whereby the “Z” timezone parameter fits the bill nicely … and when …
    • the user saves this rjmprogramming-event.ics event into the iCal Calendar application, where the event will be shown back relative to the local date and time

    The date and time functions used to make this happen are …

    1. Javascript’s Date object …

      var dd=new Date();
      var qw=eval((eval(dd.toTimeString().replace('-',' ').replace('+',' ').split(' ')[2]) - eval(dd.toTimeString().replace('-',' ').replace('+',' ').split(' ')[2] % 100)) / 100) + eval((0.0 + eval(dd.toTimeString().replace('-',' ').replace('+',' ').split(' ')[2] % 100)) / 60.0);
      if (dd.toTimeString().indexOf('+') != -1) qw=-qw;
      document.getElementById('tz').value=qw;
    2. Javascript’s Date object’s toTimeString method (as shown above) to glean the local timezone offset, and its opposite
    3. PHP’s DateTime object …

      $di="PT" . str_replace("-","",urldecode($_POST['tz'])) . "H";
      $parsed_date = DateTime::createFromFormat('Ymd:His', $ts);
      if (strpos(urldecode($_POST['tz']), "-") !== false) {
      $parsed_date->sub(new DateInterval($di));
      } else {
      $parsed_date->add(new DateInterval($di));
      }
      $outts = $parsed_date->format('Ymd:His');

    4. PHP’s DateTime object’s createFromFormat constructor method (as above) to create a DateTime object from the passed through user details
    5. PHP’s DateInterval object
    6. PHP’s DateTime object’s add and/or sub methods (as above) to create a DateTime object with a DateInterval offset to UTC (or GMT) (expressed in hours)
    7. PHP’s DateInterval object’s format method (as above) to end up with a UTC (or GMT) expression of date and time to be placed into the rjmprogramming-event.ics iCal message

    We’ll probably be revisiting with improvements soon, but we hope you try it for yourself.


    Previous relevant WebEx Prerecording Primer Tutorial is shown below.

    WebEx Prerecording Primer Tutorial

    WebEx Prerecording Primer Tutorial

    We’ve been trying out WebEx (by Cisco) prerecording as a video conferencing idea as an alternative to …

    … regarding video conferencing products we’ve tried at this blog.

    Have to say, WebEx is great, even with respect to the “wide eyed and bushy tailed” reaction “this little black duck” has to all these networky communicaty ideas on the net (at least we spelt “net” correctly).

    Have to thank my wife, Maree, for her expertise and the facilities her company, Thomson Reuters, supplies for the serving of WebEx recordings … thanks everyone. Have been assured they are periodically deleted, and my lame impersonations of the old “ducks on the wall” can rest in peace shortly.

    And so, we have a slideshow starting with a WebEx email link to join a meeting, and we pan down the email to show you other WebEx functionalities, such as adding a Calendar reference to the meeting time, and though we haven’t shown you detail here, rest assured it handles timezone scenarios very well, unless you lie about living in Antarctica, that is … sorry, scientists in Antarctica reading this blog posting … all 237 of you.

    During this “earlier than today exploration of WebEx” session the necessary software installs just happened for this MacBook Pro Mac OS X laptop as if we were shelling peas … it’s always good to have some handy when installing any software. So we won’t show you this unless we deem it essential at a later date. You can perhaps do as I did, and ask a real WebEx user invite you to a meeting, to set yourself up. In fact, today’s session meeting creation time you may notice is well in the past from that earlier introductory learning session Maree and I had, and you can bring back up that old email, and resurrect that meeting again and again, if you like … am not sure if there is an expiry date on this too, like with server stored WebEx prerecordings.

    So also rest assured, WebEx handles …

    • video via webcam on your device
    • audio via microphone on your device (“Use Computer”) or via a phone line
    • the synchronization of the two above
    • mobile devices

    Did you know?

    A .ics extension file, as you can see being used as an email attachment file extension in is, as explained in this link‘s sublink

    ICS is a global format for calendar files widely being utilized by various calendar and email programs including Google Calendar, Apple iCal, and Microsoft Outlook. These files enable users to share and publish information directly from their calendars over email or via uploading it to the world wide web.

    … as helping interface meetings to online calendar appointments. Cute, huh?!

    If this was interesting you may be interested in this too.


    If this was interesting you may be interested in this too.


    If this was interesting you may be interested in this too.


    If this was interesting you may be interested in this too.


    If this was interesting you may be interested in this too.


    If this was interesting you may be interested in this too.


    If this was interesting you may be interested in this too.


    If this was interesting you may be interested in this too.


    If this was interesting you may be interested in this too.


    If this was interesting you may be interested in this too.


    If this was interesting you may be interested in this too.


    If this was interesting you may be interested in this too.

    Posted in eLearning, Operating System, Software, Tutorials | Tagged , , , , , , , , , , , , , , , , , , , , , , , , , | Leave a comment

    Image Conversions via PHP GD Browsing Tutorial

    Image Conversions via PHP GD Browsing Tutorial

    Image Conversions via PHP GD Browsing Tutorial

    As well as the recent Image Conversions via PHP GD URL Tutorial‘s input data modes of use

    • relative URLs (to the RJM Programming domain) … and we see why we may have left this like this … we wanted to allow for image file specifications … something quite involved (but might be contemplated in a reduced functionality sense into the future …) regarding the first of two new URL modus operandi additions to functionality, those being …
    • absolute URL single image file … and …
    • image data URI single image … and today we want to add …
    • local image file browsing via the Javascript environment based File API

    … and as we got this new input mode functionality option going we widened the processing scope in the changed convert_wildcard.php‘s image conversion PHP web application to …

    • offer video creation functionality when several browsed image files are selected … and/or …
    • offer animated GIF creation functionality when several browsed image files are selected

    The allowance for multiple selection browsing helped out by the changed client_browsing.htm client side HTML and Javascript inhouse helper helped out here.


    Previous relevant Image Conversions via PHP GD URL Tutorial is shown below.

    Image Conversions via PHP GD URL Tutorial

    Image Conversions via PHP GD URL Tutorial

    The PHP inhouse Image Converter web application last talked about at Image Conversions via PHP GD Overlay Reveal Tutorial got a revisit today. It’s been more than two years, and that amount of separation sometimes gives you the chance to “go back to square one” and not be caught in amongst the “labyrinth of thought” as you get too far into complex optional logics you might apply to a web application project.

    And what stood out to us, on this revisit? It was the image input options that immediately stuck out to us, in that it used to be limited to …

    • relative URLs (to the RJM Programming domain) … and we see why we may have left this like this … we wanted to allow for image file specifications … something quite involved (but might be contemplated in a reduced functionality sense into the future …) regarding the first of two new URL modus operandi additions to functionality, those being …
    • absolute URL single image file … and …
    • image data URI single image

    Of course, should the absolute URL web servers allow such access, this opens up whole new vistas of functionality possibility here.

    Both new URL modus operandi above used an HTML iframe (shown along with an HTML form referenced later, also) …

    <?php echo ”

    <iframe style=display:none; id=ifi name=ifi src=./convert_wildcard.php></iframe>
    <form method=POST action='/convert_wildcard.php' target=ifi style=display:none;>
    <input type=hidden name=absimg id=absimg value=''></input><input id=sabsi type=submit value=Submit style=display:none;></input></form>

    “; ?>

    … but in two interestingly different ways … well, you had to be there!

    absolute URL single image file
    <?php echo ”

    function lookforabsolute(ino) {
    if (ino.value.indexOf('data:') == 0 && ino.value.indexOf('image/') != -1) {
    document.getElementById('absimg').value=ino.value;
    document.getElementById('sabsi').click();
    } else if (ino.value.indexOf('//') != -1) {
    ino.title=ino.value;
    document.getElementById('ifi').src='./convert_wildcard.php?absimg=' + encodeURIComponent('http://' + ino.value.split('//')[1]);
    }

    }

    “; ?>
    … meeting up with receiving PHP logic, skeletally …
    <?php

    $gabsimg='';
    if (isset($_GET['absimg'])) {
    $gabsimg=$_GET['absimg'];
    }
    if (isset($_POST['absimg'])) {
    // Perform necessary $_POST scenario populating of $gabsimg
    }
    if ($gabsimg != '') { //isset($_GET['absimg'])) {
    // Perform necessary image URL processing here adjusting parent.document.getElementById('ispec') in the process
    }

    ?>
    image data URI single image
    <?php echo ”

    function lookforabsolute(ino) {
    if (ino.value.indexOf('data:') == 0 && ino.value.indexOf('image/') != -1) {
    document.getElementById('absimg').value=ino.value;
    document.getElementById('sabsi').click();
    }
    else if (ino.value.indexOf('//') != -1) {
    ino.title=ino.value;
    document.getElementById('ifi').src='./convert_wildcard.php?absimg=' + encodeURIComponent('http://' + ino.value.split('//')[1]);
    }
    }

    “; ?>
    … meeting up with receiving PHP logic, skeletally …
    <?php

    $gabsimg='';
    if (isset($_GET['absimg'])) {
    // Perform necessary $_GET scenario populating of $gabsimg
    }
    if (isset($_POST['absimg'])) {
    $gabsimg=$_POST['absimg'];
    if (strpos(('~' . $gabsimg), '~data') !== false) {
    $dcont=str_replace(' ','+',urldecode($gabsimg));
    if (strpos($dcont, 'image/') !== false && strpos($dcont, ';base64,') !== false) {
    $inext=strtolower(explode(';base64,', explode('image/', $dcont)[1])[0]);
    $imgname='/tmp/mycw_' . server_remote_addr() . '.' . $inext;
    file_put_contents($imgname, base64_decode(explode(';base64,', $dcont)[1]));
    echo '<html><body onload=" parent.document.getElementById(' . "'ispec'" . ').value=' . "'" . $imgname . "'" . '; parent.document.getElementById(' . "'ispec'" . ').title=' . "''" . '; "></body></html>';
    exit;
    }
    }
    }
    if ($gabsimg != '') { //isset($_GET['absimg'])) {
    // Perform necessary image URL processing here adjusting parent.document.getElementById('ispec') in the process, if not already done above (and not getting here)
    }

    ?>

    … the most obvious reason for divergent approaches happening here being that data URIs are large and need $_POST[] form navigation while absolute URLs are short enough to use the simpler $_GET[] approach in the changed convert_wildcard.php‘s image conversion PHP web application.

    Did you know?

    Are you interested in the image data of a particular date at this WordPress Blog? Maybe you want to apply some GD filtering to it, download it, and move on? We don’t mind such image data repurposing. Well, for the example date 19th February, 2025 (ie. 20250219) you could …

    … readying you for your PHP GD based filtering “smarts” to apply, and process, and download … etcetera etcetera etcetera.


    Previous relevant Image Conversions via PHP GD Overlay Reveal Tutorial is shown below.

    Image Conversions via PHP GD Overlay Reveal Tutorial

    Image Conversions via PHP GD Overlay Reveal Tutorial

    Around here, we have two words we like to approach the topic of “web design”, where it meets “practicality”, with …

    And so, onto yesterday’s Image Conversions via PHP GD Multiple Actions Tutorial‘s progress with our Image Conversions via PHP GD web application we were keen to think that an “overlay” concept could be part of the workings, at the image creation stage of the web design. Supposing you have a set of images that go to make up the whole, we can use the new “Merge” option as per …

    Show me “Merge” Image Conversion “Overlay” Idea below …


    … we found was most feasible with PNG input image files, with transparency.

    And then, onto yesterday’s Image Conversions via PHP GD Multiple Actions Tutorial‘s progress with our Image Conversions via PHP GD web application we were keen to think that an “reveal” concept (a bit like a cartoon, perhaps) could be part of the workings, at the image creation stage of the web design. Supposing you have a set of images that go to make up the whole, we can use the new “Merge” option as per …

    Show me “Merge” Image Conversion “Reveal” Idea below …


    … we found was most feasible with …

    • PNG input image file(s) … self made or source from a free source such as Pixabay, thanks
    • cut up via Gimp‘s …
      1. Selection Tools -> Free Select … and …
      2. Edit -> Clear … and …
      3. File -> Export As… -> .png (set “Save color values from Transparent Pixels” on)
    • open PNG in Paintbrush and File -> Save As… -> JPEG
    • use “Merge” option of Image Conversion via GD web application

    And then, at least with our MAMP local Apache web server PHP version we can also offer …

    • crop … nominate a colour in images to crop via, and gets a look in with today’s animated GIF tutorial picture
    • transparent … nominate a colour in images to make transparent

    … additional functionalities in the changed convert_wildcard.php‘s image conversion PHP web application.


    Previous relevant Image Conversions via PHP GD Multiple Actions Tutorial is shown below.

    Image Conversions via PHP GD Multiple Actions Tutorial

    Image Conversions via PHP GD Multiple Actions Tutorial

    We’ve waited a while preparing for today’s release of “multiple actions” functionality onto yesterday’s Image Conversions via PHP GD Transformations Tutorial. From how we see it we had a choice of two approaches to delivering this new functionality …

    • start using select (ie. dropdown) element multiple attribute approach … but, especially because we are separating GD “Filters” into one dropdown and “Transformations” into another, we think it would be better to …
    • start prefixing ✔ (&#10004; tick) emoji to selected action(s) to apply to any images involved in the conversions

    The ✔ (&#10004; tick) emoji was enough for us, yet we wanted to indicate to the user the order of actions they’ve entered. To do this we were helped out by Javascript sort methodology used in …

    <?php echo ”

    function sortsel(insel) {
    var sv=insel.value;
    var optsa=insel.innerHTML.split('</option>');
    var sopta=optsa.sort();
    var newih='';
    for (var ioj=0; ioj<sopta.length; ioj++) {
    newih+=sopta[ioj] + '</option>';
    }
    insel.innerHTML=newih;
    insel.value=sv;
    }

    “; ?>

    … accepting the GD “Filter” dropdown object as a parameter. But how is that going to help when “action” titles will just determine the sort order? Well, the select (ie. dropdown) element here is made up of …

    <?php echo ”

    <option value=\”action_desc\”>Action Desc</option>

    “; ?>

    … parts where we started defining the first two this way

    <?php echo ”

    <option class=\”opt000\” value=\”\”>Image Filter …</option><option class=\”opt001\” value=\” \”>Image Filter Ask Arguments …</option>

    “; ?>

    … and then changed our dropdown onchange event logic supplementing a new “whenmulti” total picture data member that is now maintained …

    <?php echo ”

    var nextcls=2;

    function zoomsame(tvo, tvv) {
    var tv=tvo.value;
    var rest='';
    var getcls='';
    if (tvv != '') { tv=tvv; }
    var pa=null;
    if (tv.trim() == '' && ('' + tv.length) != '0') { aska=true; }
    if (tv.trim() != '') {
    if (document.getElementById('whenmulti').value.indexOf(tv + '=') != -1) {
    rest=tv + '=' + document.getElementById('whenmulti').value.split(tv + '=')[1].split(';')[0];
    if (document.getElementById('whenmulti').value.indexOf(rest + ';') != -1) { rest+=';'; }
    document.getElementById('whenmulti').value=document.getElementById('whenmulti').value.replace(rest, '');
    if (document.getElementById('whenmulti').value != '') {
    tvo.name=document.getElementById('whenmulti').value.split('=')[0];
    } else {
    tvo.name='sfilter';
    }
    tvo.innerHTML=tvo.innerHTML.replace(' value=\"' + tv + '\">' + tvo.innerHTML.split(' value=\"' + tv + '\">')[1].split(' ')[0] + ' ', ' value=\"' + tv + '\">');
    getcls=tvo.innerHTML.split(' value=\"' + tv + '\">')[0].split(' class=\"')[eval(-1 + tvo.innerHTML.split(' value=\"' + tv + '\">')[0].split(' class=\"').length)].split('\"')[0];
    if (getcls != '') { tvo.innerHTML=tvo.innerHTML.replace(' class=\"' + getcls + '\"', ''); }
    return '';
    }
    if (tvo.outerHTML.indexOf(' name=') == -1) { tvo.name=tv.trim(); } else if (('' + tvo.name) == 'sfilter') { tvo.name=tv.trim(); }

    if (aska && askastr.indexOf(';' + tv.trim().toLowerCase() + ';') != -1) {
    pa=prompt('Optionally enter argument(s) for ' + tv.trim(), askastr.split(';' + tv.trim().toLowerCase() + ';')[1].split(';')[0]);
    if (pa != null) {
    if (pa.trim() == '') { pa=null; }
    }
    }
    if (pa != null) {
    if (document.getElementById('whenmulti').value == '') {
    document.getElementById('whenmulti').value=tv + '=' + pa;
    } else {
    document.getElementById('whenmulti').value+=';' + tv + '=' + pa;
    document.getElementById('presub').innerHTML+='<input type=hidden name=' + tv.trim() + ' value=></input>';
    }

    if (('' + pa.split(',').length) == '3') {
    document.getElementById('rotation').name='args';
    document.getElementById('rotation').value=pa;
    } else {
    document.getElementById('rotation').name='arg1';
    document.getElementById('rotation').value=pa;
    }
    tvo.innerHTML=tvo.innerHTML.replace(' value=\"' + tv + '\">', ' class=\"opt' + ('00' + nextcls).slice(-3) + '\" value=\"' + tv + '\">&#10004; ');
    nextcls++;
    sortsel(tvo);

    } else {
    if (document.getElementById('whenmulti').value == '') {
    document.getElementById('whenmulti').value=tv + '=' + '';
    } else {
    document.getElementById('whenmulti').value+=';' + tv + '=' + '';
    document.getElementById('presub').innerHTML+='<input type=hidden name=' + tv.trim() + ' value=></input>';
    }
    tvo.innerHTML=tvo.innerHTML.replace(' value=\"' + tv + '\">', ' class=\"opt' + ('00' + nextcls).slice(-3) + '\" value=\"' + tv + '\">&#10004; ');
    nextcls++;

    document.getElementById('rotation').name='rotation';
    document.getElementById('rotation').value='' + document.getElementById('trot').value;
    sortsel(tvo);
    }
    if (tv.trim().toLowerCase() == 'redo') {
    redo();
    } //alert(11);
    //}
    }
    }

    “; ?>

    … helping out that Javascript sort with disruptive, but useful, class attribute inclusion into those option subelement outerHTML (which makes up the select element innerHTML) content in the changed convert_wildcard.php‘s image conversion PHP web application.


    Previous relevant Image Conversions via PHP GD Transformations Tutorial is shown below.

    Image Conversions via PHP GD Transformations Tutorial

    Image Conversions via PHP GD Transformations Tutorial

    In today’s work progressing yesterday’s Image Conversions via PHP GD Command Line Tutorial‘s outcomes …

    • we add into the GD “Filtering” thinking, some “Transformations” …

      … thinking and functionality … and then …
    • we cater for a “curl” mode of use … by, up in that top newish block of code “recreating” a non-existant $argv[] and $argc to precede any “command line” code that fills in $_POST[] array to join in with “surfing the web” mode of use …
      <?php

      $beginswitch=false;
      $nextquality=false;
      $argnext=false;
      $results="";
      $curlstr="";
      $iscurl=false;

      if (!isset($argc) && isset($_GET['command'])) { // curl mode of use eg. curl "ht
      tp://localhost:8888/convert_wildcard.php?command=x*.jpg+-q+76+-negate+.jpeg"
      $curlstr="convert_wildcard.php " . str_replace('+',' ',urldecode($_GET['command']));
      $argv=explode(" ", $curlstr);
      $argc=sizeof($argv);
      if (strpos(strtolower($_SERVER['SERVER_NAME']), 'rjmprogramming.com.au') !== false) { $iscurl=true; }
      }


      if (isset($argc)) { // command line mode of use eg. php convert_wildcard.php x*.jpg -q 76 -negate .jpeg
      $results="\n";
      for ($ii=1; $ii<$argc; $ii++) { if (trim($argv[$ii]) != '') { if ($nextquality) { $nextquality=false; $_POST['quality']=str_replace('%','',$argv[$ii]); } else if (strpos($argv[$ii], '-quality') !== false || strpos($argv[$ii], '-QUALITY') !== false) { $beginswitch=true; if (strpos($argv[$ii],'=') !== false) { $_POST['quality']=str_replace('%','',explode('=', $argv[$ii])[1]); } else if (strlen($argv[$ii]) > 8) {
      $_POST['quality']=str_replace('%','',substr($argv[$ii], 8));
      } else {
      $nextquality=true;
      }
      } else if (strpos($argv[$ii], '-q') !== false || strpos($argv[$ii], '-Q') !== false) {
      $beginswitch=true;
      if (strpos($argv[$ii],'=') !== false) {
      $_POST['quality']=str_replace('%','',explode('=', $argv[$ii])[1]);
      } else if (strlen($argv[$ii]) > 2) {
      $_POST['quality']=str_replace('%','',substr($argv[$ii], 2));
      } else {
      $nextquality=true;
      }
      } else if (substr($argv[$ii],0,1) == '-') {
      $beginswitch=true;
      if (strpos($argv[$ii],'=') !== false) {
      $_POST[substr(strtolower(explode('=',$argv[$ii])[0]),1)]='';
      if (sizeof(explode(',',explode('=',$argv[$ii])[1])) == 3) {
      $_POST['args']=explode('=',$argv[$ii])[1];
      } else {
      $_POST['arg1']=explode('=',$argv[$ii])[1];
      }
      } else {
      $_POST[substr(strtolower(explode('=',$argv[$ii])[0]),1)]='';
      $argnext=true;
      }
      } else if (!isset($_POST['ispec'])) {
      $_POST['ispec']=$argv[$ii];
      } else if (!$beginswitch) {
      $_POST['ispec'].="," . $argv[$ii];
      } else if (substr($argv[$ii],0,1) == '.' || strlen($argv[$ii]) == 3) {
      $argnext=false;
      $_POST['outext']=str_replace("..", ".", "." . $argv[$ii]);
      } else if ($argnext) {
      $argnext=false;
      if (sizeof(explode(',',$argv[$ii])) == 3) {
      $_POST['args']=$argv[$ii];
      } else {
      $_POST['arg1']=$argv[$ii];
      }
      }
      }
      }
      }

      ?>
      … and then rearranged (where first blue section just used to be echo ) the last bit of PHP code …
      <?php

      if (isset($argc) && !$iscurl) {
      echo openthese($results);
      } else {
      $htmlis=
      "<!doctyle html>
      <html>
      <head>
      <title>Image Conversions via PHP GD - RJM Programming - October, 2022</title>
      ... etcetera etcetera etcetera ...
      <select id=extsel style=display:none; id=xxxoutext><option value=''>Enter output relative image file extension [.jpeg]</option><option value=.jpeg>.jpeg</option><option value=.jpg>.jpg</option><option value=.png>.png</option><option value=.gif>.gif</option><option value=.JPEG>.JPEG</option><option value=.JPG>.JPG</option><option value=.PNG>.PNG</option><option value=.GIF>.GIF</option></select>
      </body>
      </html>";
      if (!$iscurl) {
      echo $htmlis;
      } else {
      $phtmlis="temphtml.html";
      while (file_exists($phtmlis)) {
      $phtmlis=str_replace(".htm", "0.htm", $phtmlis);
      }
      file_put_contents($phtmlis, $htmlis);
      //exec("cd " . dirname(__FILE__) . " ; open " . $phtmlis); // . " ; rm -f " . $phtmlis);
      echo "Please issue command ...\nopen http://www.rjmprogramming.com.au/" . $phtmlis . " \n ... to see results. Omit the open word for Windows. You have up to the next minute to do this. ";
      }
      }


      ?>
      … making a MAMP curl usage such as …

      curl "http://localhost:8888/convert_wildcard.php?command=x*.jpg+-q+76+-negate+.jpeg"

      … open the images in your default desktop image editor, while an RJM Programming incarnation such as …

      curl "http://www.rjmprogramming.com.au/convert_wildcard.php?command=wh*.*g*+-q+76+-negate+.jpeg"

      … will return a string such as …

      Please issue command …
      open http://www.rjmprogramming.com.au/temphtml.html
      … to see results. Omit the open word for Windows. You have up to the next minute to do this.

      … and a quick witted user will copy and paste that open http://www.rjmprogramming.com.au/temphtml.html quickly enough to see a webpage offering image download functionalities

    … in the changed convert_wildcard.php‘s image conversion PHP web application.

    Did you know?

    With that last “rjmprogramming.com.au” curl scenario it occurs to us, you could optionally do a multiple command (or use type ahead buffer on Windows) like …


    curl "http://www.rjmprogramming.com.au/convert_wildcard.php?command=wh*.*g*+-q+76+-negate+.jpeg" ; open http://www.rjmprogramming.com.au/temphtml.html

    … for a 99% chance of success without having to worry about the “too quick” copying and pasting in less than a minute caper! Blurb output will correct you if temphtml.html is not the go.

    Or think procedural scripting where Windows has *.bat batch files and macOS or Linux have shells like sh or bash or csh or ksh (our favourite, called Korn Shell). A scheduled procedural crontab command action part could be a Korn Shell one liner like …


    ksh -c 'curl "http://www.rjmprogramming.com.au/convert_wildcard.php?command=wh*.*g*+-q+76+-negate+.jpeg" ; open http://www.rjmprogramming.com.au/temphtml.html'

    Then a Korn Shell script we’ll call “daily.ksh” on macOS or Linux could contain …


    #!/bin/ksh
    curl "http://www.rjmprogramming.com.au/convert_wildcard.php?command=wh*.*g*+-q+76+-negate+.jpeg"
    open http://www.rjmprogramming.com.au/temphtml.html
    exit

    … then, thinking macOS or Linux, make it (perhaps too) executable via


    chmod 777 daily.ksh

    … and make happen via …


    ./daily.ksh


    Previous relevant Image Conversions via PHP GD Command Line Tutorial is shown below.

    Image Conversions via PHP GD Command Line Tutorial

    Image Conversions via PHP GD Command Line Tutorial

    In the online woooooorrrrrlllllddd (of surfing the net in a web browser) we hope you see “nothing to see here” different to yesterday’s Image Conversions via PHP GD Filters Tutorial‘s exploits with our image conversion PHP web application.

    And though this is the boring partner in …

    • must not break previous logics …
    • must work for new functionality

    … adage around here trying to keep “backward compatibility” as you move forward with a project, it is, often, the most important partner.

    As for today, it is more likely our RJM Programming users of the changed convert_wildcard.php will never access our …

    • new command line mode of use … adding to existant …
    • surfing the net (in a web browser) mode of use … and perhaps into the future a …
    • curl mode of use

    … but we think this PHP web application really suits a command line mode of use, given that it so suits a …

    • download to local web server, such as Apache/PHP MAMP environment … and once there …
    • you can control “php” as a command “verb” on the command line (by adding MAMP’s php executable relevant to your version used, to your operating system PATH environment variable), as convenient, to the point that a command line command such as …

      php convert_wildcard.php x*.jpg -q 76 -negate .jpeg

      … reads as a pretty self-explanatory way to achieve a result string such as …


      New image x.jpeg created …
      New image xcode__fibonacci.jpeg created …
      New image xcode_fibonacci.jpeg created …
      New image xcodefibonacci.jpeg created …
      New image xx.jpeg created …

      … as we got on our MAMP environment here

    … paradigm set of conditions, quite like ImageMagick and its command line (“convert” for macOS and Linux and “magick.exe” for Windows) image conversion functionality.

    The PHP changes were 95% a single block of new code, featuring a “first time for us” filling in of $_POST[] array “linkages” to “surfing the net” code in the new “command line” isset($argc) == true mode of use scenario blocks of code, near the top …

    <?php

    $beginswitch=false;
    $nextquality=false;
    $argnext=false;
    $results="";

    if (isset($argc)) { // command line mode of use eg. php convert_wildcard.php x*.jpg -q 76 -negate .jpeg
    $results="\n";
    for ($ii=1; $ii<$argc; $ii++) {
    if (trim($argv[$ii]) != '') {
    if ($nextquality) {
    $nextquality=false;
    $_POST['quality']=str_replace('%','',$argv[$ii]);
    } else if (strpos($argv[$ii], '-quality') !== false || strpos($argv[$ii], '-QUALITY') !== false) {
    $beginswitch=true;
    if (strpos($argv[$ii],'=') !== false) {
    $_POST['quality']=str_replace('%','',explode('=', $argv[$ii])[1]);
    } else if (strlen($argv[$ii]) > 8) {
    $_POST['quality']=str_replace('%','',substr($argv[$ii], 8));
    } else {
    $nextquality=true;
    }
    } else if (strpos($argv[$ii], '-q') !== false || strpos($argv[$ii], '-Q') !== false) {
    $beginswitch=true;
    if (strpos($argv[$ii],'=') !== false) {
    $_POST['quality']=str_replace('%','',explode('=', $argv[$ii])[1]);
    } else if (strlen($argv[$ii]) > 2) {
    $_POST['quality']=str_replace('%','',substr($argv[$ii], 2));
    } else {
    $nextquality=true;
    }
    } else if (substr($argv[$ii],0,1) == '-') {
    $beginswitch=true;
    if (strpos($argv[$ii],'=') !== false) {
    $_POST[substr(strtolower(explode('=',$argv[$ii])[0]),1)]='';
    if (sizeof(explode(',',explode('=',$argv[$ii])[1])) == 3) {
    $_POST['args']=explode('=',$argv[$ii])[1];
    } else {
    $_POST['arg1']=explode('=',$argv[$ii])[1];
    }
    } else {
    $_POST[substr(strtolower(explode('=',$argv[$ii])[0]),1)]='';
    $argnext=true;
    }
    } else if (!isset($_POST['ispec'])) {
    $_POST['ispec']=$argv[$ii];
    } else if (!$beginswitch) {
    $_POST['ispec'].="," . $argv[$ii];
    } else if (substr($argv[$ii],0,1) == '.' || strlen($argv[$ii]) == 3) {
    $argnext=false;
    $_POST['outext']=str_replace("..", ".", "." . $argv[$ii]);
    } else if ($argnext) {
    $argnext=false;
    if (sizeof(explode(',',$argv[$ii])) == 3) {
    $_POST['args']=$argv[$ii];
    } else {
    $_POST['arg1']=$argv[$ii];
    }
    }
    }
    }
    }

    ?>


    Previous relevant Image Conversions via PHP GD Filters Tutorial is shown below.

    Image Conversions via PHP GD Filters Tutorial

    Image Conversions via PHP GD Filters Tutorial

    Once in the (PHP) GD-land of yesterday’s Image Conversions via PHP GD Primer Tutorial, you’d be mad not to facilitate some image filtering which GD is so good at. And so, we have included an optional usage dropdown as per …

    … into the mix. We add this select element “dropdown” within the HTML form method=POST action=”Here’s looking at you kid” arrangement. Initially it gets assigned just an ID attribute, with no NAME attribute, which is an ideal arrangement when functionality is optional. And so, if the user chooses a real “filter” here it gets assigned an appropriate NAME attribute as per the PHP’s Javascript dropdown onchange event logic …

    <?php echo ”

    function zoomsame(tvo) {
    var tv=tvo.value;
    var pa=null;
    if (tv.trim() == '' && ('' + tv.length) != '0') { aska=true; }
    if (tv.trim() != '') {
    tvo.name=tv.trim();
    if (aska && askastr.indexOf(';' + tv.trim().toLowerCase() + ';') != -1) {
    pa=prompt('Optionally enter argument(s) for ' + tv.trim(), askastr.split(';' + tv.trim().toLowerCase() + ';')[1].split(';')[0]);
    if (pa != null) {
    if (pa.trim() == '') { pa=null; }
    }
    }
    if (pa != null) {
    if (('' + pa.split(',').length) == '3') {
    document.getElementById('rotation').name='args';
    document.getElementById('rotation').value=pa;
    } else {
    document.getElementById('rotation').name='arg1';
    document.getElementById('rotation').value=pa;
    }
    } else {
    document.getElementById('rotation').name='rotation';
    document.getElementById('rotation').value='' + document.getElementById('trot').value;
    }
    if (tv.trim().toLowerCase() == 'redo') {
    redo();
    } //alert(11);
    //}
    }
    }

    “; ?>

    … turning a “display useful only” HTML dropdown element into one whose value is transferred with self-navigation to interest the PHP “recall” logic …

    <?php

    function ourimagecreatefromfile($zfilename) {
    global $div_img, $ext;
    //file_put_contents("qwe.qweaa", $zfilename);
    if (isset($_GET['emboss']) || isset($_POST['emboss'])) {
    //file_put_contents("qwe.qwe", str_replace(' ','+',urldecode($_GET['emboss'])) . str_replace(' ','+',urldecode($_POST['emboss'])) . $zfilename);
    //file_put_contents("qwe.qwex", $_SERVER['HTTP_REFERER']);
    $jm_php = imagecreatefromstring(ourfile_get_contents(str_replace(' ','+',urldecode($_GET['emboss'])) . str_replace(' ','+',urldecode($_POST['emboss'])) . $zfilename));
    $emboss = getpostmaybe('arg1',array([-2, -1, 0], [-1, 1, 1], [0, 1, 2]));
    //file_put_contents("qwe.qwexx", $_SERVER['HTTP_REFERER']);
    //imageconvolution($jm_php, $emboss, 1, 0);
    imagefilter($jm_php, IMG_FILTER_EMBOSS);
    return $jm_php; //$new_name = 'anewimage0.jpg';
    $nj=0;
    while (file_exists('anewimage' . $nj . '.jpg')) {
    $nj++;
    $new_name = 'anewimage' . $nj . '.jpg';
    }
    imagejpeg($jm_php, $new_name);
    $qpzm='data:image/jpeg;base64,' . base64_encode(ourfile_get_contents($new_name));
    imagedestroy($jm_php);
    unlink($new_name);
    //file_put_contents("qwe.qwez", $_SERVER['HTTP_REFERER']);
    if (strpos($_SERVER['HTTP_REFERER'], "/pdfimageplustext.php") !== false) {
    //file_put_contents("qwe.qwey", "<!doctype html><html><body onload=\" if (parent.document.getElementById('slideshow')) { parent.document.getElementById('slideshow').value=parent.undobackup('" . datauriit($qpzm) . "'); parent.forcescale(); } \"></body></html>");
    echo "<!doctype html><html><body onload=\" if (parent.document.getElementById('slideshow')) { parent.document.getElementById('slideshow').value=parent.undobackup('" . datauriit($qpzm) . "'); parent.forcescale(); } \"></body></html>";
    exit;
    }
    return $qpzm;
    } else if (isset($_GET['edge']) || isset($_POST['edge'])) {
    $jm_php = imagecreatefromstring(ourfile_get_contents(str_replace(' ','+',urldecode($_GET['edge'])) . str_replace(' ','+',urldecode($_POST['edge'])) . $zfilename));
    $edge_detect = getpostmaybe('arg1',array([-1, -1, -1], [-1, 8, -1], [-1, -1, -1]));
    imageconvolution($jm_php, $edge_detect, 1, 0);
    imageconvolution($jm_php, $edge_detect, 1, 255);
    return $jm_php; //$new_name = 'anewimage0.jpg';
    $nj=0;
    while (file_exists('anewimage' . $nj . '.jpg')) {
    $nj++;
    $new_name = 'anewimage' . $nj . '.jpg';
    }
    imagejpeg($jm_php, $new_name);
    $qpzm='data:image/jpeg;base64,' . base64_encode(ourfile_get_contents($new_name));
    imagedestroy($jm_php);
    unlink($new_name);
    if (strpos($_SERVER['HTTP_REFERER'], "/pdfimageplustext.php") !== false) {
    echo "<!doctype html><html><body onload=\" if (parent.document.getElementById('slideshow')) { parent.document.getElementById('slideshow').value=parent.undobackup('" . datauriit($qpzm) . "'); parent.forcescale(); } \"></body></html>";
    exit;
    }
    return $qpzm;
    } else if (isset($_GET['negedge']) || isset($_POST['negedge'])) {
    $jm_php = imagecreatefromstring(ourfile_get_contents(str_replace(' ','+',urldecode($_GET['negedge'])) . str_replace(' ','+',urldecode($_POST['negedge'])) . $zfilename));
    $edge_detect = getpostmaybe('arg1',array([-1, -1, -1], [-1, 8, -1], [-1, -1, -1]));
    imageconvolution($jm_php, $edge_detect, 1, 0);
    //imageconvolution($jm_php, $edge_detect, 1, 255);
    return $jm_php; //$new_name = 'anewimage0.jpg';
    $nj=0;
    while (file_exists('anewimage' . $nj . '.jpg')) {
    $nj++;
    $new_name = 'anewimage' . $nj . '.jpg';
    }
    imagejpeg($jm_php, $new_name);
    $qpzm='data:image/jpeg;base64,' . base64_encode(ourfile_get_contents($new_name));
    imagedestroy($jm_php);
    unlink($new_name);
    if (strpos($_SERVER['HTTP_REFERER'], "/pdfimageplustext.php") !== false) {
    echo "<!doctype html><html><body onload=\" if (parent.document.getElementById('slideshow')) { parent.document.getElementById('slideshow').value=parent.undobackup('" . datauriit($qpzm) . "'); parent.forcescale(); } \"></body></html>";
    exit;
    }
    return $qpzm;
    } else if (isset($_GET['sharpen']) || isset($_POST['sharpen'])) {
    $jm_php = imagecreatefromstring(ourfile_get_contents(str_replace(' ','+',urldecode($_GET['sharpen'])) . str_replace(' ','+',urldecode($_POST['sharpen'])) . $zfilename));
    $sharpen = getpostmaybe('arg1',array([0, -1, 0], [-1, 5, -1], [0, -1, 0]));
    imageconvolution($jm_php, $sharpen, 1, 0);
    return $jm_php; //$new_name = 'anewimage0.jpg';
    $nj=0;
    while (file_exists('anewimage' . $nj . '.jpg')) {
    $nj++;
    $new_name = 'anewimage' . $nj . '.jpg';
    }
    imagejpeg($jm_php, $new_name);
    $qpzm='data:image/jpeg;base64,' . base64_encode(ourfile_get_contents($new_name));
    imagedestroy($jm_php);
    unlink($new_name);
    if (strpos($_SERVER['HTTP_REFERER'], "/pdfimageplustext.php") !== false) {
    echo "<!doctype html><html><body onload=\" if (parent.document.getElementById('slideshow')) { parent.document.getElementById('slideshow').value=parent.undobackup('" . datauriit($qpzm) . "'); parent.forcescale(); } \"></body></html>";
    exit;
    }
    return $qpzm;
    } else if (isset($_GET['boxblur']) || isset($_POST['boxblur'])) {
    $jm_php = imagecreatefromstring(ourfile_get_contents(str_replace(' ','+',urldecode($_GET['boxblur'])) . str_replace(' ','+',urldecode($_POST['boxblur'])) . $zfilename));
    $box_blur = getpostmaybe('arg1',array([1, 1, 1], [1, 1, 1], [1, 1, 1]));
    imageconvolution($jm_php, $box_blur, 9, 0);
    return $jm_php; //$new_name = 'anewimage0.jpg';
    $nj=0;
    while (file_exists('anewimage' . $nj . '.jpg')) {
    $nj++;
    $new_name = 'anewimage' . $nj . '.jpg';
    }
    imagejpeg($jm_php, $new_name);
    $qpzm='data:image/jpeg;base64,' . base64_encode(ourfile_get_contents($new_name));
    imagedestroy($jm_php);
    unlink($new_name);
    if (strpos($_SERVER['HTTP_REFERER'], "/pdfimageplustext.php") !== false) {
    echo "<!doctype html><html><body onload=\" if (parent.document.getElementById('slideshow')) { parent.document.getElementById('slideshow').value=parent.undobackup('" . datauriit($qpzm) . "'); parent.forcescale(); } \"></body></html>";
    exit;
    }
    return $qpzm;
    } else if (isset($_GET['grayscale']) || isset($_POST['grayscale'])) {
    $jm_php = imagecreatefromstring(ourfile_get_contents(str_replace(' ','+',urldecode($_GET['grayscale'])) . str_replace(' ','+',urldecode($_POST['grayscale'])) . $zfilename));
    imagefilter($jm_php, IMG_FILTER_GRAYSCALE);
    return $jm_php; //$new_name = 'anewimage0.jpg';
    $nj=0;
    while (file_exists('anewimage' . $nj . '.jpg')) {
    $nj++;
    $new_name = 'anewimage' . $nj . '.jpg';
    }
    imagejpeg($jm_php, $new_name);
    $qpzm='data:image/jpeg;base64,' . base64_encode(ourfile_get_contents($new_name));
    imagedestroy($jm_php);
    unlink($new_name);
    if (strpos($_SERVER['HTTP_REFERER'], "/pdfimageplustext.php") !== false) {
    echo "<!doctype html><html><body onload=\" if (parent.document.getElementById('slideshow')) { parent.document.getElementById('slideshow').value=parent.undobackup('" . datauriit($qpzm) . "'); parent.forcescale(); } \"></body></html>";
    exit;
    }
    return $qpzm;
    } else if (isset($_GET['gaussianianblur']) || isset($_POST['gaussianblur'])) {
    $jm_php = imagecreatefromstring(ourfile_get_contents(str_replace(' ','+',urldecode($_GET['gaussianblur'])) . str_replace(' ','+',urldecode($_POST['gaussianblur'])) . $zfilename));
    imagefilter($jm_php, IMG_FILTER_GAUSSIAN_BLUR);
    return $jm_php; //$new_name = 'anewimage0.jpg';
    $nj=0;
    while (file_exists('anewimage' . $nj . '.jpg')) {
    $nj++;
    $new_name = 'anewimage' . $nj . '.jpg';
    }
    imagejpeg($jm_php, $new_name);
    $qpzm='data:image/jpeg;base64,' . base64_encode(ourfile_get_contents($new_name));
    imagedestroy($jm_php);
    unlink($new_name);
    if (strpos($_SERVER['HTTP_REFERER'], "/pdfimageplustext.php") !== false) {
    echo "<!doctype html><html><body onload=\" if (parent.document.getElementById('slideshow')) { parent.document.getElementById('slideshow').value=parent.undobackup('" . datauriit($qpzm) . "'); parent.forcescale(); } \"></body></html>";
    exit;
    }
    return $qpzm;
    } else if (isset($_GET['selectiveblur']) || isset($_POST['selectiveblur'])) {

    $jm_php = imagecreatefromstring(ourfile_get_contents(str_replace(' ','+',urldecode($_GET['selectiveblur'])) . str_replace(' ','+',urldecode($_POST['selectiveblur'])) . $zfilename));
    imagefilter($jm_php, IMG_FILTER_SELECTIVE_BLUR);
    return $jm_php; //$new_name = 'anewimage0.jpg';
    $nj=0;
    while (file_exists('anewimage' . $nj . '.jpg')) {
    $nj++;
    $new_name = 'anewimage' . $nj . '.jpg';
    }
    imagejpeg($jm_php, $new_name);
    $qpzm='data:image/jpeg;base64,' . base64_encode(ourfile_get_contents($new_name));
    imagedestroy($jm_php);
    unlink($new_name);
    if (strpos($_SERVER['HTTP_REFERER'], "/pdfimageplustext.php") !== false) {
    echo "<!doctype html><html><body onload=\" if (parent.document.getElementById('slideshow')) { parent.document.getElementById('slideshow').value=parent.undobackup('" . datauriit($qpzm) . "'); parent.forcescale(); } \"></body></html>";
    exit;
    }
    return $qpzm;

    } else if (isset($_GET['negate']) || isset($_POST['negate'])) {
    $jm_php = imagecreatefromstring(ourfile_get_contents(str_replace(' ','+',urldecode($_GET['negate'])) . str_replace(' ','+',urldecode($_POST['negate'])) . $zfilename));
    imagefilter($jm_php, IMG_FILTER_NEGATE);
    return $jm_php; //$new_name = 'anewimage0.jpg';
    $nj=0;
    while (file_exists('anewimage' . $nj . '.jpg')) {
    $nj++;
    $new_name = 'anewimage' . $nj . '.jpg';
    }
    imagejpeg($jm_php, $new_name);
    $qpzm='data:image/jpeg;base64,' . base64_encode(ourfile_get_contents($new_name));
    imagedestroy($jm_php);
    unlink($new_name);
    if (strpos($_SERVER['HTTP_REFERER'], "/pdfimageplustext.php") !== false) {
    echo "<!doctype html><html><body onload=\" if (parent.document.getElementById('slideshow')) { parent.document.getElementById('slideshow').value=parent.undobackup('" . datauriit($qpzm) . "'); parent.forcescale(); } \"></body></html>";
    exit;
    }
    return $qpzm;
    } else if (isset($_GET['colourizered']) || isset($_POST['colourizered']) || isset($_GET['colorizered']) || isset($_POST['colorizered'])) {
    $jm_php = imagecreatefromstring(ourfile_get_contents(str_replace(' ','+',urldecode($_GET['colourizered'])) . str_replace(' ','+',urldecode($_POST['colourizered'])) . $zfilename));
    imagefilter($jm_php, IMG_FILTER_COLORIZE, getpostmaybe('arg1',rand(0,255)), 0, 0); //, 100);
    return $jm_php; //$new_name = 'anewimage0.jpg';
    $nj=0;
    while (file_exists('anewimage' . $nj . '.jpg')) {
    $nj++;
    $new_name = 'anewimage' . $nj . '.jpg';
    }
    imagejpeg($jm_php, $new_name);
    $qpzm='data:image/jpeg;base64,' . base64_encode(ourfile_get_contents($new_name));
    imagedestroy($jm_php);
    unlink($new_name);
    if (strpos($_SERVER['HTTP_REFERER'], "/pdfimageplustext.php") !== false) {
    echo "<!doctype html><html><body onload=\" if (parent.document.getElementById('slideshow')) { parent.document.getElementById('slideshow').value=parent.undobackup('" . datauriit($qpzm) . "'); parent.forcescale(); } \"></body></html>";
    exit;
    }
    return $qpzm;
    } else if (isset($_GET['colourizegreen']) || isset($_POST['colourizegreen']) || isset($_GET['colorizegreen']) || isset($_POST['colorizegreen'])) {
    $jm_php = imagecreatefromstring(ourfile_get_contents(str_replace(' ','+',urldecode($_GET['colourizegreen'])) . str_replace(' ','+',urldecode($_POST['colourizegreen'])) . $zfilename));
    imagefilter($jm_php, IMG_FILTER_COLORIZE, 0, getpostmaybe('arg1',rand(0,255)), 0); //, 100);
    return $jm_php; //$new_name = 'anewimage0.jpg';
    $nj=0;
    while (file_exists('anewimage' . $nj . '.jpg')) {
    $nj++;
    $new_name = 'anewimage' . $nj . '.jpg';
    }
    imagejpeg($jm_php, $new_name);
    $qpzm='data:image/jpeg;base64,' . base64_encode(ourfile_get_contents($new_name));
    imagedestroy($jm_php);
    unlink($new_name);
    if (strpos($_SERVER['HTTP_REFERER'], "/pdfimageplustext.php") !== false) {
    echo "<!doctype html><html><body onload=\" if (parent.document.getElementById('slideshow')) { parent.document.getElementById('slideshow').value=parent.undobackup('" . datauriit($qpzm) . "'); parent.forcescale(); } \"></body></html>";
    exit;
    }
    return $qpzm;
    } else if (isset($_GET['colourize']) || isset($_POST['colourize']) || isset($_GET['colorize']) || isset($_POST['colorize'])) {
    $jm_php = imagecreatefromstring(ourfile_get_contents(str_replace(' ','+',urldecode($_GET['colourize'])) . str_replace(' ','+',urldecode($_POST['colourize'])) . $zfilename));
    imagefilter($jm_php, IMG_FILTER_COLORIZE, getpostmaybe('arg1',rand(0, 255)), getpostmaybe('arg2',rand(0, 255)), getpostmaybe('arg3',rand(0, 255))); //, 100);
    return $jm_php; //$new_name = 'anewimage0.jpg';
    $nj=0;
    while (file_exists('anewimage' . $nj . '.jpg')) {
    $nj++;
    $new_name = 'anewimage' . $nj . '.jpg';
    }
    imagejpeg($jm_php, $new_name);
    $qpzm='data:image/jpeg;base64,' . base64_encode(ourfile_get_contents($new_name));
    imagedestroy($jm_php);
    unlink($new_name);
    if (strpos($_SERVER['HTTP_REFERER'], "/pdfimageplustext.php") !== false) {
    echo "<!doctype html><html><body onload=\" if (parent.document.getElementById('slideshow')) { parent.document.getElementById('slideshow').value=parent.undobackup('" . datauriit($qpzm) . "'); parent.forcescale(); } \"></body></html>";
    exit;
    }
    return $qpzm;
    } else if (isset($_GET['colourizeblue']) || isset($_POST['colourizeblue']) || isset($_GET['colorizeblue']) || isset($_POST['colorizeblue'])) {
    $jm_php = imagecreatefromstring(ourfile_get_contents(str_replace(' ','+',urldecode($_GET['colourizeblue'])) . str_replace(' ','+',urldecode($_POST['colourizeblue'])) . $zfilename));
    imagefilter($jm_php, IMG_FILTER_COLORIZE, 0, 0, getpostmaybe('arg1',rand(0,255))); //, 100);
    return $jm_php; //$new_name = 'anewimage0.jpg';
    $nj=0;
    while (file_exists('anewimage' . $nj . '.jpg')) {
    $nj++;
    $new_name = 'anewimage' . $nj . '.jpg';
    }
    imagejpeg($jm_php, $new_name);
    $qpzm='data:image/jpeg;base64,' . base64_encode(ourfile_get_contents($new_name));
    imagedestroy($jm_php);
    unlink($new_name);
    if (strpos($_SERVER['HTTP_REFERER'], "/pdfimageplustext.php") !== false) {
    echo "<!doctype html><html><body onload=\" if (parent.document.getElementById('slideshow')) { parent.document.getElementById('slideshow').value=parent.undobackup('" . datauriit($qpzm) . "'); parent.forcescale(); } \"></body></html>";
    exit;
    }
    return $qpzm;
    } else if (isset($_GET['pixellate']) || isset($_POST['pixellate']) || isset($_GET['pixelate']) || isset($_POST['pixelate'])) {
    $jm_php = imagecreatefromstring(ourfile_get_contents(str_replace(' ','+',urldecode($_GET['pixellate'])) . str_replace(' ','+',urldecode($_POST['pixellate'])) . $zfilename));
    imagefilter($jm_php, IMG_FILTER_PIXELATE, getpostmaybe('arg1',rand(1, 9))); // was 3
    return $jm_php; //$new_name = 'anewimage0.jpg';
    $nj=0;
    while (file_exists('anewimage' . $nj . '.jpg')) {
    $nj++;
    $new_name = 'anewimage' . $nj . '.jpg';
    }
    imagejpeg($jm_php, $new_name);
    $qpzm='data:image/jpeg;base64,' . base64_encode(ourfile_get_contents($new_name));
    imagedestroy($jm_php);
    unlink($new_name);
    if (strpos($_SERVER['HTTP_REFERER'], "/pdfimageplustext.php") !== false) {
    echo "<!doctype html><html><body onload=\" if (parent.document.getElementById('slideshow')) { parent.document.getElementById('slideshow').value=parent.undobackup('" . datauriit($qpzm) . "'); parent.forcescale(); } \"></body></html>";
    exit;
    }
    return $qpzm;
    } else if (isset($_GET['smooth']) || isset($_POST['smooth'])) {
    $jm_php = imagecreatefromstring(ourfile_get_contents(str_replace(' ','+',urldecode($_GET['smooth'])) . str_replace(' ','+',urldecode($_POST['smooth'])) . $zfilename));
    imagefilter($jm_php, IMG_FILTER_SMOOTH, getpostmaybe('arg1',rand(5, 35))); // was -1924.124
    return $jm_php; //$new_name = 'anewimage0.jpg';
    $nj=0;
    while (file_exists('anewimage' . $nj . '.jpg')) {
    $nj++;
    $new_name = 'anewimage' . $nj . '.jpg';
    }
    imagejpeg($jm_php, $new_name);
    $qpzm='data:image/jpeg;base64,' . base64_encode(ourfile_get_contents($new_name));
    imagedestroy($jm_php);
    unlink($new_name);
    if (strpos($_SERVER['HTTP_REFERER'], "/pdfimageplustext.php") !== false) {
    echo "<!doctype html><html><body onload=\" if (parent.document.getElementById('slideshow')) { parent.document.getElementById('slideshow').value=parent.undobackup('" . datauriit($qpzm) . "'); parent.forcescale(); } \"></body></html>";
    exit;
    }
    return $qpzm;
    } else if (isset($_GET['contrast']) || isset($_POST['contrast'])) {
    $jm_php = imagecreatefromstring(ourfile_get_contents(str_replace(' ','+',urldecode($_GET['contrast'])) . str_replace(' ','+',urldecode($_POST['contrast'])) . $zfilename));
    imagefilter($jm_php, IMG_FILTER_CONTRAST, getpostmaybe('arg1',rand(-100, 100))); // was -90
    return $jm_php; //$new_name = 'anewimage0.jpg';
    $nj=0;
    while (file_exists('anewimage' . $nj . '.jpg')) {
    $nj++;
    $new_name = 'anewimage' . $nj . '.jpg';
    }
    imagejpeg($jm_php, $new_name);
    $qpzm='data:image/jpeg;base64,' . base64_encode(ourfile_get_contents($new_name));
    imagedestroy($jm_php);
    unlink($new_name);
    if (strpos($_SERVER['HTTP_REFERER'], "/pdfimageplustext.php") !== false) {
    echo "<!doctype html><html><body onload=\" if (parent.document.getElementById('slideshow')) { parent.document.getElementById('slideshow').value=parent.undobackup('" . datauriit($qpzm) . "'); parent.forcescale(); } \"></body></html>";
    exit;
    }
    return $qpzm;
    } else if (isset($_GET['brightness']) || isset($_POST['brightness'])) {
    $jm_php = imagecreatefromstring(ourfile_get_contents(str_replace(' ','+',urldecode($_GET['brightness'])) . str_replace(' ','+',urldecode($_POST['brightness'])) . $zfilename));
    imagefilter($jm_php, IMG_FILTER_BRIGHTNESS, getpostmaybe('arg1',rand(-255, 255))); // was 98
    return $jm_php; //$new_name = 'anewimage0.jpg';
    $nj=0;
    while (file_exists('anewimage' . $nj . '.jpg')) {
    $nj++;
    $new_name = 'anewimage' . $nj . '.jpg';
    }
    imagejpeg($jm_php, $new_name);
    $qpzm='data:image/jpeg;base64,' . base64_encode(ourfile_get_contents($new_name));
    imagedestroy($jm_php);
    unlink($new_name);
    if (strpos($_SERVER['HTTP_REFERER'], "/pdfimageplustext.php") !== false) {
    echo "<!doctype html><html><body onload=\" if (parent.document.getElementById('slideshow')) { parent.document.getElementById('slideshow').value=parent.undobackup('" . datauriit($qpzm) . "'); parent.forcescale(); } \"></body></html>";
    exit;
    }
    return $qpzm;
    } else if (isset($_GET['sketchy']) || isset($_POST['sketchy']) || isset($_GET['mean_removal']) || isset($_POST['mean_removal']) || isset($_GET['mean-removal']) || isset($_POST['mean-removal'])) {
    $jm_php = imagecreatefromstring(ourfile_get_contents(str_replace(' ','+',urldecode($_GET['sketchy'])) . str_replace(' ','+',urldecode($_POST['sketchy'])) . $zfilename));
    imagefilter($jm_php, IMG_FILTER_MEAN_REMOVAL);
    return $jm_php; //$new_name = 'anewimage0.jpg';
    $nj=0;
    while (file_exists('anewimage' . $nj . '.jpg')) {
    $nj++;
    $new_name = 'anewimage' . $nj . '.jpg';
    }
    imagejpeg($jm_php, $new_name);
    $qpzm='data:image/jpeg;base64,' . base64_encode(ourfile_get_contents($new_name));
    imagedestroy($jm_php);
    unlink($new_name);
    if (strpos($_SERVER['HTTP_REFERER'], "/pdfimageplustext.php") !== false) {
    echo "<!doctype html><html><body onload=\" if (parent.document.getElementById('slideshow')) { parent.document.getElementById('slideshow').value=parent.undobackup('" . datauriit($qpzm) . "'); parent.forcescale(); } \"></body></html>";
    exit;
    }
    return $qpzm;
    } else if (isset($_GET['flipvertical']) || isset($_POST['flipvertical'])) {
    $jm_php = imagecreatefromstring(ourfile_get_contents(str_replace(' ','+',urldecode($_GET['flipvertical'])) . str_replace(' ','+',urldecode($_POST['flipvertical'])) . $zfilename));
    $jm_php=ourImageFlip($jm_php, '1'); //imageflip($jm_php, IMG_FLIP_VERTICAL);
    return $jm_php; //$new_name = 'anewimage0.jpg';
    $nj=0;
    while (file_exists('anewimage' . $nj . '.jpg')) {
    $nj++;
    $new_name = 'anewimage' . $nj . '.jpg';
    }
    imagejpeg($jm_php, $new_name);
    $qpzm='data:image/jpeg;base64,' . base64_encode(ourfile_get_contents($new_name));
    imagedestroy($jm_php);
    unlink($new_name);
    if (strpos($_SERVER['HTTP_REFERER'], "/pdfimageplustext.php") !== false) {
    echo "<!doctype html><html><body onload=\" if (parent.document.getElementById('slideshow')) { parent.document.getElementById('slideshow').value=parent.undobackup('" . datauriit($qpzm) . "'); parent.forcescale(); } \"></body></html>";
    exit;
    }
    return $qpzm;
    } else if (isset($_GET['fliphorizontal']) || isset($_POST['fliphorizontal'])) {
    $jm_php = imagecreatefromstring(ourfile_get_contents(str_replace(' ','+',urldecode($_GET['fliphorizontal'])) . str_replace(' ','+',urldecode($_POST['fliphorizontal'])) . $zfilename));
    $jm_php=ourImageFlip($jm_php, '2'); //imageflip($jm_php, IMG_FLIP_HORIZONTAL);
    return $jm_php; //$new_name = 'anewimage0.jpg';
    $nj=0;
    while (file_exists('anewimage' . $nj . '.jpg')) {
    $nj++;
    $new_name = 'anewimage' . $nj . '.jpg';
    }
    imagejpeg($jm_php, $new_name);
    $qpzm='data:image/jpeg;base64,' . base64_encode(ourfile_get_contents($new_name));
    imagedestroy($jm_php);
    unlink($new_name);
    if (strpos($_SERVER['HTTP_REFERER'], "/pdfimageplustext.php") !== false) {
    echo "<!doctype html><html><body onload=\" if (parent.document.getElementById('slideshow')) { parent.document.getElementById('slideshow').value=parent.undobackup('" . datauriit($qpzm) . "'); parent.forcescale(); } \"></body></html>";
    exit;
    }
    return $qpzm;
    } else if (isset($_GET['flip']) || isset($_POST['flip'])) {
    $jm_php = imagecreatefromstring(ourfile_get_contents(str_replace(' ','+',urldecode($_GET['flip'])) . str_replace(' ','+',urldecode($_POST['flip'])) . $zfilename));
    $jm_php=ourImageFlip($jm_php, '3'); //imageflip($jm_php, IMG_FLIP_BOTH);
    return $jm_php; //$new_name = 'anewimage0.jpg';
    $nj=0;
    while (file_exists('anewimage' . $nj . '.jpg')) {
    $nj++;
    $new_name = 'anewimage' . $nj . '.jpg';
    }
    imagejpeg($jm_php, $new_name);
    $qpzm='data:image/jpeg;base64,' . base64_encode(ourfile_get_contents($new_name));
    imagedestroy($jm_php);
    unlink($new_name);
    if (strpos($_SERVER['HTTP_REFERER'], "/pdfimageplustext.php") !== false) {
    echo "<!doctype html><html><body onload=\" if (parent.document.getElementById('slideshow')) { parent.document.getElementById('slideshow').value=parent.undobackup('" . datauriit($qpzm) . "'); parent.forcescale(); } \"></body></html>";
    exit;
    }
    return $qpzm;
    } else if (isset($_GET['rotation']) || isset($_POST['rotation'])) {
    //file_put_contents("qwe.qwe1", $zfilename);
    $jm_php = imagecreatefromstring(ourfile_get_contents(str_replace(' ','+',urldecode($_GET['flip'])) . str_replace(' ','+',urldecode($_POST['flip'])) . $zfilename));
    //file_put_contents("qwe.qwe2", $zfilename);
    if (isset($_GET['rotation'])) {
    $iim_php=imagerotate($jm_php, floatval(trim(str_replace('+',' ',urldecode($_GET['rotation'])))), 0);
    } else if (isset($_POST['rotation'])) {
    //file_put_contents("qwe.qwe3", '' . (trim(str_replace('+',' ',urldecode($_POST['rotation'])))));
    $iim_php=imagerotate($jm_php, floatval(trim(str_replace('+',' ',urldecode($_POST['rotation'])))), 0);
    //file_put_contents("qwe.qwe4", '' . floatval(trim(str_replace('+',' ',urldecode($_POST['rotation'])))));
    } else {
    $iim_php=imagerotate($jm_php, 0.0, 0);
    }
    //file_put_contents("qwe.qwe5", $zfilename);
    return $jm_php; //$new_name = 'anewimage0.jpg';
    $nj=0;
    while (file_exists('anewimage' . $nj . '.jpg')) {
    $nj++;
    $new_name = 'anewimage' . $nj . '.jpg';
    }
    //file_put_contents("qwe.qwe6", $zfilename);
    imagejpeg($iim_php, $new_name);
    //file_put_contents("qwe.qwe7", $zfilename);
    $qpzm='data:image/jpeg;base64,' . base64_encode(ourfile_get_contents($new_name));
    //file_put_contents("qwe.qwe8", $zfilename);
    imagedestroy($jm_php);
    imagedestroy($iim_php);
    //file_put_contents("qwe.qwe9", $zfilename);
    unlink($new_name);
    if (strpos($_SERVER['HTTP_REFERER'], "/pdfimageplustext.php") !== false) {
    echo "<!doctype html><html><body onload=\" if (parent.document.getElementById('slideshow')) { parent.document.getElementById('slideshow').value=parent.undobackup('" . datauriit($qpzm) . "'); parent.forcescale(); } \"></body></html>";
    exit;
    }
    return $qpzm;
    }
    return imagecreatefromstring(file_get_contents($zfilename)); // 'data:image/' . substr($ext,1) . ";base64," . base64_encode(ourfile_get_contents($zfilename));
    }

    ?>

    … PHP code that may be familiar looking to readers of our recent PDF Image and Text Nodes Windows Files Tutorial thread of blog postings. Feel free to try the changed convert_wildcard.php PHP web application you can also try below.


    Previous relevant Image Conversions via PHP GD Primer Tutorial is shown below.

    Image Conversions via PHP GD Primer Tutorial

    Image Conversions via PHP GD Primer Tutorial

    Regular readers at this place will know about our admiration for ImageMagick and its command line (“convert” for macOS and Linux and “magick.exe” for Windows) image conversion functionality. Even so, ImageMagick is not capable of …


    convert filespec*.*g* *.jpeg

    … type of image conversion, in bulk, kind of processing (which Gimp offered with its sadly departed Bimp conversion software in the past). But tailored PHP use of the GD (image manipulation) library, helped out by (good ol’) PHP glob, is!

    And so, we’ve written a “proof of concept” converter that you can run at the RJM Programming domain, but we’d recommend for use with an Apache/PHP local web server like MAMP is! (Two in one blog posting is a record … is!)

    Get into MAMP, and you might want to download convert_wildcard.php PHP source code to MAMP’s Document Root folder. Else, try it here or below …

    If this was interesting you may be interested in this too.


    If this was interesting you may be interested in this too.


    If this was interesting you may be interested in this too.


    If this was interesting you may be interested in this too.


    If this was interesting you may be interested in this too.


    If this was interesting you may be interested in this too.


    If this was interesting you may be interested in this too.


    If this was interesting you may be interested in this too.

    Posted in eLearning, Event-Driven Programming, Tutorials | Tagged , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , | Leave a comment

    Haiku Image Tutorial

    Haiku Image Tutorial

    Haiku Image Tutorial

    Were you around when Python Cowsay API Cartoon Speech Media Tutorial‘s “genesis tutorial” called Python Cowsay API Primer Tutorial intimated …

    … with an integration purpose in mind

    ? And then, sometime between then and now were you a “Doubting Thomas” thinking we’d forgotten about that statement? And while we’re at it, where were you on February 6, 2025 03:01 AEST?

    I’m conflicted if your answers are “No” and “Robbing a bank” but, be that as it may, “we did have an integration purpose in mind” and we’ve come back to it via Haiku poetry, and a web application we wrote some time ago regarding them, and it interfaced to the theme of “the integration purpose in mind” … well you had to be there, said Putricia?!

    Yes, it’s the case that hoping for the umpteenth re-researching whether anything manageable Linux wise can match what the great macOS say command has done for Speech to Text relations since Audrey Hepburn’s speech … and coming back with a “No” yet again … we started looking at it a bit more laterally and thought 😜😜 …

    But what would the Cow say?

    But seriously, no, we just stumbled onto the wonderful cowsay Python API / Command-line tool and wanted to … thinking laterally … have “cowsay” smarts be included into our changed macos_say_record.php PHP Voiceover inhouse web application, itself interfaced to by our changed haiku_animated_gif.html Haiku creating inhouse web application you can also try below …

    … so that our changed latest draft can interface in a popup window scenario.


    Previous relevant Python Cowsay API Cartoon Speech Media Tutorial is shown below.

    Python Cowsay API Cartoon Speech Media Tutorial

    Python Cowsay API Cartoon Speech Media Tutorial

    As soon as a web application talks about image slides, as we have been dealing with allowing for the creation of cartoons with our recent cowsay Python API / Command-line tool interfacing PHP web application, maybe as Louis Lumière did many years ago, it brings out media thoughts regarding “moving pictures”. We use, here, at our RJM Programming AlmaLinux web server, the great Open Source ffmpeg to help create such media, in today’s case …

    • video
    • animated GIF

    … productions using those image slides created via the (again, Open Source) cowsay Python API / Command-line tool …

    <?php

    if (isset($_GET['getvideo'])) {
    $lenv='1';
    if (isset($_GET['len'])) {
    $lenv=$_GET['len'];
    }
    if ($_GET['getvideo'] == '1' && $lenv == '0') {
    echo "<html><body onload=\" if (parent.document.getElementById('divvideo')) { parent.document.getElementById('divvideo').innerHTML='<video id=myvideo controls><source id=mysource type=video/mp4 src=' + String.fromCharCode(39) + 'data:video/mp4;base64," . base64_encode(file_get_contents('/tmp/video' . server_remote_addr() . '.mp4')) . "' + String.fromCharCode(39) + '></source></video>'; } else if (parent.document.getElementById('mysource')) { parent.document.getElementById('mysource').src='data:video/mp4;base64," . base64_encode(file_get_contents('/tmp/video' . server_remote_addr() . '.mp4')) . "'; } else { parent.document.getElementById('divmedia').innerHTML+='<br><br><p id=pvd>Video version below ... <a style=display:inline-block; href=#myh1>Back to top ...</a></p><br><div id=divvideo><video id=myvideo controls><source id=mysource type=video/mp4 src=' + String.fromCharCode(39) + 'data:video/mp4;base64," . base64_encode(file_get_contents('/tmp/video' . server_remote_addr() . '.mp4')) . "' + String.fromCharCode(39) + '></source></video></div>'; } setTimeout(function(){ parent.document.getElementById('pvd').scrollIntoView(); }, 2000); \"></body></html>";
    } else {
    if (file_exists('/tmp/video' . server_remote_addr() . '.mp4')) {
    unlink('/tmp/video' . server_remote_addr() . '.mp4');
    }
    exec('ffmpeg -framerate 2 -i /tmp/slide_' . server_remote_addr() . '-%03d.png -vcodec libx264 -crf 22 /tmp/video' . server_remote_addr() . '.mp4');
    echo "<html><body onload=\" if (parent.document.getElementById('divvideo')) { parent.document.getElementById('divvideo').innerHTML='<video id=myvideo controls><source id=mysource type=video/mp4 src=' + String.fromCharCode(39) + 'data:video/mp4;base64," . base64_encode(file_get_contents('/tmp/video' . server_remote_addr() . '.mp4')) . "' + String.fromCharCode(39) + '></source></video>'; } else if (parent.document.getElementById('mysource')) { parent.document.getElementById('mysource').src='data:video/mp4;base64," . base64_encode(file_get_contents('/tmp/video' . server_remote_addr() . '.mp4')) . "'; } else { parent.document.getElementById('divmedia').innerHTML+='<br><br><p id=pvd>Video version below ... <a style=display:inline-block; href=#myh1>Back to top ...</a></p><br><div id=divvideo><video id=myvideo controls><source id=mysource type=video/mp4 src=' + String.fromCharCode(39) + 'data:video/mp4;base64," . base64_encode(file_get_contents('/tmp/video' . server_remote_addr() . '.mp4')) . "' + String.fromCharCode(39) + '></source></video></div>'; } setTimeout(function(){ parent.document.getElementById('pvd').scrollIntoView(); }, 2000); \"></body></html>";
    }
    exit;
    } else if (isset($_GET['getagif'])) {
    $lenv='1';
    if (isset($_GET['len'])) {
    $lenv=$_GET['len'];
    }
    if ($_GET['getvideo'] == '1' && $lenv == '0') {
    echo "<html><body onload=\" if (parent.document.getElementById('mygif')) { parent.document.getElementById('mygif').src='data:image/gif;base64," . base64_encode(file_get_contents('/tmp/agif' . server_remote_addr() . '.gif')) . "'; } else { parent.document.getElementById('divmedia').innerHTML+='<br><br><p id=pag>Animated GIF version below ... <a style=display:inline-block; href=#myh1>Back to top ...</a></p><br><img id=mygif src=data:image/gif;base64," . base64_encode(file_get_contents('/tmp/agif' . server_remote_addr() . '.gif')) . "></img>'; } setTimeout(function(){ parent.document.getElementById('pag').scrollIntoView(); }, 2000); \"></body></html>";
    } else {
    if (file_exists('/tmp/agif' . server_remote_addr() . '.gif')) {
    unlink('/tmp/agif' . server_remote_addr() . '.gif');
    }
    exec('ffmpeg -framerate 2 -i /tmp/slide_' . server_remote_addr() . '-%03d.png /tmp/agif' . server_remote_addr() . '.gif');
    echo "<html><body onload=\" if (parent.document.getElementById('mygif')) { parent.document.getElementById('mygif').src='data:image/gif;base64," . base64_encode(file_get_contents('/tmp/agif' . server_remote_addr() . '.gif')) . "'; } else { parent.document.getElementById('divmedia').innerHTML+='<br><br><p id=pag>Animated GIF version below ... <a style=display:inline-block; href=#myh1>Back to top ...</a></p><br><img id=mygif src=data:image/gif;base64," . base64_encode(file_get_contents('/tmp/agif' . server_remote_addr() . '.gif')) . "></img>'; } setTimeout(function(){ parent.document.getElementById('pag').scrollIntoView(); }, 2000); \"></body></html>";
    }
    exit;
    }

    ?>

    … as a new optional piece of additional functionality offered in our changed “fifth draft” (picking up from Python Cowsay API Cartoon Speech Content Tutorial‘s fourth draft, and further to yesterday’s Text to Image via ImageMagick Primer Tutorial) Cartoon creation and email sharing capable PHP web application you can also try below.


    Previous relevant Text to Image via ImageMagick Primer Tutorial is shown below.

    Text to Image via ImageMagick Primer Tutorial

    Text to Image via ImageMagick Primer Tutorial

    Why would a “Primer” tutorial point at a “well along the way” one? Well, a few reasons really …

    Yes, the great ImageMagick (and we’re using it’s command line “convert” command here to make this happen) can convert text to images (ie. HTML img elements). Now, we’re not saying you always get perfect matches here, but it is akin to mere mortal dreamers think of as “intelligent scanning”. So, we wanted to have this sidetrack, and we will be resuming “normal transmission” shortly?!

    We’ll leave you with some cowsay.php new relevant PHP code to ponder …

    <?php

    if (isset($_GET['fontlist'])) {
    $selpop='';
    if (!file_exists('/tmp/imfl.txt')) {
    exec('convert -list font > /tmp/imfl.txt');
    }
    $fcont=file_get_contents('/tmp/imfl.txt');
    if (strpos($fcont, 'family: ') !== false) {
    $fcs=explode('family: ', $fcont);
    for ($iuy=1; $iuy<sizeof($fcs); $iuy++) {
    if (strpos($selpop, '>' . explode("\n", $fcs[$iuy])[0] . '<') === false) {
    $selpop.="\n selo.innerHTML+='<option value=' + String.fromCharCode(39) + '" . explode("\n", $fcs[$iuy])[0] . "' + String.fromCharCode(39) + '>" . explode("\n", $fcs[$iuy])[0] . "</option>'; \n";
    }
    }
    if ($selpop != '') {
    echo "<html><body onload=\" var selos=parent.document.getElementsByTagName('select'); if (eval('' + selos.length) > 0) { var selo=selos[eval(-1 + selos.length)]; " . $selpop . " selo.style.display='inline-block'; selo.style.backgroundColor='#f0f0f0'; } \"></body></html>";
    }
    }
    exit;
    } else if (isset($_POST['text'])) {
    $perlemoji='';
    $emojilabbit="@- "; // vs perl
    $iex='png';
    $fnt='Courier';
    $wdt='800';
    $hgt='800';
    $psiz='36';
    $fcol='black';
    $bcol='white';
    if (isset($_POST['ext'])) { $iex=str_replace('+',' ',urldecode($_POST['ext'])); }
    if (isset($_POST['ffam'])) { $fnt=str_replace('+',' ',urldecode($_POST['ffam'])); }
    if (isset($_POST['width'])) { $pwdt=str_replace('+',' ',urldecode($_POST['width'])); }
    if (isset($_POST['height'])) { $hgt=str_replace('+',' ',urldecode($_POST['height'])); }
    if (isset($_POST['ptsize'])) { $psiz=str_replace('+',' ',urldecode($_POST['ptsize'])); }
    if (isset($_POST['fcol'])) { $fcol=str_replace('+',' ',urldecode($_POST['fcol'])); }
    if (isset($_POST['bcol'])) { $bcol=str_replace('+',' ',urldecode($_POST['bcol'])); }
    $slidename='/tmp/imagerequest_' . server_remote_addr() . '-0.' . $iex;
    file_put_contents('/tmp/imagerequest_' . server_remote_addr() . '-0.txt', str_replace('+',' ',urldecode($_POST['text'])));
    file_put_contents('/tmp/maybeemojisP.txt', htmlspecialchars(str_replace('+',' ',urldecode($_POST['text'])), ENT_COMPAT,'UTF-8', true));
    // yes no &#129684;
    if (strpos(str_replace('+',' ',urldecode($_POST['text'])), '&#') !== false || strpos(str_replace('+',' ',urldecode($_POST['text'])), '&#') !== false) { // thanks to https://usage.imagemagick.org/text/#unicode
    $outsofar=''; // '\x{201C}Unicode \x{2018}\x{263A}\x{2019} Please\x{201D}'
    if (strpos(str_replace('+',' ',urldecode($_POST['text'])), '&#') !== false) {
    $outs=explode('&#', str_replace('+',' ',urldecode($_POST['text'])));
    $outsofar=$outs[0];
    for ($ivx=1; $ivx<sizeof($outs); $ivx++) {
    $decis=explode(';', $outs[$ivx])[0];
    if (str_replace('0','',str_replace('1','',str_replace('2','',str_replace('3','',str_replace('4','',str_replace('5','',str_replace('6','',str_replace('7','',str_replace('8','',str_replace('9','',$decis)))))))))) != '') {
    if (substr(strtolower($decis),0,1) == 'x') {
    $outsofar.="\\x{" . substr($decis,1) . "}";
    } else {
    $outsofar.="\\x{" . $decis . "}";
    }
    } else {
    $outsofar.="\\x{" . dechex($decis) . "}";
    }
    $outsofar.=substr($outs[$ivx],strlen($decis . ';'));
    }
    } else if (strpos(str_replace('+',' ',urldecode($_POST['text'])), '&#') !== false) {
    $outs=explode('&#', str_replace('+',' ',urldecode($_POST['text'])));
    $outsofar=$outs[0];
    for ($ivx=1; $ivx<sizeof($outs); $ivx++) {
    $decis=explode(';', $outs[$ivx])[0];
    if (str_replace('0','',str_replace('1','',str_replace('2','',str_replace('3','',str_replace('4','',str_replace('5','',str_replace('6','',str_replace('7','',str_replace('8','',str_replace('9','',$decis)))))))))) != '') {
    if (substr(strtolower($decis),0,1) == 'x') {
    $outsofar.="\\x{" . substr($decis,1) . "}";
    } else {
    $outsofar.="\\x{" . $decis . "}";
    }
    } else {
    $outsofar.="\\x{" . dechex($decis) . "}";
    }
    $outsofar.=substr($outs[$ivx],strlen($decis . ';'));
    }
    }
    $labbit=$emojilabbit;
    $perlemoji="perl -e 'binmode(STDOUT, \":utf8\"); print \"" . str_replace("\n", "\x{000A}", $outsofar) . '";' . "' | ";
    }
    if (strpos(str_replace('+',' ',urldecode($_POST['text'])), "\\") !== false) {
    if ($perlemoji == '') { $labbit='"$(cat /tmp/imagerequest_' . server_remote_addr() . '-0.txt | ' . " sed '/\\\\/s//\\\\\\\\/g')" . '" '; }
    file_put_contents('/tmp/imag.cmd', $perlemoji . 'convert -background "' . $bcol . '" -fill "' . $fcol . '" -size ' . $wdt . 'x' . $hgt . ' -font ' . $fnt . ' -pointsize ' . $psiz . ' label:' . $labbit . ' ' . $slidename);
    exec($perlemoji . 'convert -background "' . $bcol . '" -fill "' . $fcol . '" -size ' . $wdt . 'x' . $hgt . ' -font ' . $fnt . ' -pointsize ' . $psiz . ' label:' . $labbit . ' ' . $slidename);
    exec('chmod 777 ' . $slidename);
    } else {
    if ($perlemoji == '') { $labbit='"$(cat /tmp/imagerequest_' . server_remote_addr() . '-0.txt)' . '" '; }
    file_put_contents('/tmp/imaG.cmd', $perlemoji . 'convert -background "' . $bcol . '" -fill "' . $fcol . '" -size ' . $wdt . 'x' . $hgt . ' -font ' . $fnt . ' -pointsize ' . $psiz . ' label:' . $labbit . ' ' . $slidename . ' ; chmod 777 ' . $slidename);
    exec($perlemoji . 'convert -background "' . $bcol . '" -fill "' . $fcol . '" -size ' . $wdt . 'x' . $hgt . ' -font ' . $fnt . ' -pointsize ' . $psiz . ' label:' . $labbit . ' ' . $slidename);
    exec('chmod 777 ' . $slidename);
    }
    if (isset($_POST['raw'])) {
    header('Content-Type: image/' . $iex);
    echo file_get_contents($slidename);
    unlink($slidename);
    unlink('/tmp/imagerequest_' . server_remote_addr() . '-0.txt');
    exit;
    } else {
    echo "<html>
    <body onload=\"
    if (window.parent != window.self) {
    var cnvs=parent.document.getElementsByTagName('canvas');
    if (eval('' + cnvs.length) > 0) {
    var imgsis=new Image();
    imgsis.onload=function(event){
    var canvasis=cnvs[0];
    var cntxis=canvasis.getContext('2d');
    cntxis.drawImage(event.target, 0, 0);
    };
    imgsis.src='data:image/" . $iex . ";base64," . base64_encode(file_get_contents($slidename)) . "';
    } else {
    var imgs=parent.document.getElementsByTagName('img');
    if (eval('' + imgs.length) > 0) {
    imgs[0].src='data:image/" . $iex . ";base64," . base64_encode(file_get_contents($slidename)) . "';
    } else if (document.body.innerHTML == '') {
    document.body.innerHTML='<img src=data:image/" . $iex . ";base64," . base64_encode(file_get_contents($slidename)) . "></img><style> * { margin:0 0 0 0; padding:0 0 0 0; } img { border-top: 8px solid " . $bcol . "; }</style>';
    } else {
    document.body.innerHTML+='<br><img src=data:image/" . $iex . ";base64," . base64_encode(file_get_contents($slidename)) . "></img>';
    }
    }
    } else if (document.body.innerHTML == '') {
    document.body.innerHTML='<img src=data:image/" . $iex . ";base64," . base64_encode(file_get_contents($slidename)) . "></img><style> * { margin:0 0 0 0; padding:0 0 0 0; } img { border-top: 8px solid " . $bcol . "; }</style>';
    } else {
    document.body.innerHTML+='<br><img src=data:image/" . $iex . ";base64," . base64_encode(file_get_contents($slidename)) . "></img>';
    }
    \"></body></html>";
    unlink('/tmp/imagerequest_' . server_remote_addr() . '-0.txt');
    try {
    unlink($slidename);
    } catch(Exception $esdw) { }
    }
    exit;
    } else if (isset($_GET['text'])) {
    $perlemoji='';
    $emojilabbit="@- "; // vs perl
    $iex='png';
    $fnt='Courier';
    $wdt='800';
    $hgt='800';
    $psiz='36';
    $fcol='black';
    $bcol='white';
    if (isset($_GET['ext'])) { $iex=str_replace('+',' ',urldecode($_GET['ext'])); }
    if (isset($_GET['ffam'])) { $fnt=str_replace('+',' ',urldecode($_GET['ffam'])); }
    if (isset($_GET['width'])) { $pwdt=str_replace('+',' ',urldecode($_GET['width'])); }
    if (isset($_GET['height'])) { $hgt=str_replace('+',' ',urldecode($_GET['height'])); }
    if (isset($_GET['ptsize'])) { $psiz=str_replace('+',' ',urldecode($_GET['ptsize'])); }
    if (isset($_GET['fcol'])) { $fcol=str_replace('+',' ',urldecode($_GET['fcol'])); }
    if (isset($_GET['bcol'])) { $bcol=str_replace('+',' ',urldecode($_GET['bcol'])); }
    $slidename='/tmp/imagerequest_' . server_remote_addr() . '-0.' . $iex;
    file_put_contents('/tmp/imagerequest_' . server_remote_addr() . '-0.txt', str_replace('+',' ',urldecode($_GET['text'])));
    file_put_contents('/tmp/maybeemojisG.txt', htmlspecialchars(str_replace('+',' ',urldecode($_GET['text'])), ENT_COMPAT,'UTF-8', true));
    // yes no &#129684;
    if (strpos(str_replace('+',' ',urldecode($_GET['text'])), '&#') !== false || strpos(str_replace('+',' ',urldecode($_GET['text'])), '&#') !== false) { // thanks to https://usage.imagemagick.org/text/#unicode
    $outsofar=''; // '\x{201C}Unicode \x{2018}\x{263A}\x{2019} Please\x{201D}'
    if (strpos(str_replace('+',' ',urldecode($_GET['text'])), '&#') !== false) {
    $outs=explode('&#', str_replace('+',' ',urldecode($_GET['text'])));
    $outsofar=$outs[0];
    for ($ivx=1; $ivx<sizeof($outs); $ivx++) {
    $decis=explode(';', $outs[$ivx])[0];
    if (str_replace('0','',str_replace('1','',str_replace('2','',str_replace('3','',str_replace('4','',str_replace('5','',str_replace('6','',str_replace('7','',str_replace('8','',str_replace('9','',$decis)))))))))) != '') {
    if (substr(strtolower($decis),0,1) == 'x') {
    $outsofar.="\\x{" . substr($decis,1) . "}";
    } else {
    $outsofar.="\\x{" . $decis . "}";
    }
    } else {
    $outsofar.="\\x{" . dechex($decis) . "}";
    }
    $outsofar.=substr($outs[$ivx],strlen($decis . ';'));
    }
    } else if (strpos(str_replace('+',' ',urldecode($_GET['text'])), '&#') !== false) {
    $outs=explode('&#', str_replace('+',' ',urldecode($_GET['text'])));
    $outsofar=$outs[0];
    for ($ivx=1; $ivx<sizeof($outs); $ivx++) {
    $decis=explode(';', $outs[$ivx])[0];
    if (str_replace('0','',str_replace('1','',str_replace('2','',str_replace('3','',str_replace('4','',str_replace('5','',str_replace('6','',str_replace('7','',str_replace('8','',str_replace('9','',$decis)))))))))) != '') {
    if (substr(strtolower($decis),0,1) == 'x') {
    $outsofar.="\\x{" . substr($decis,1) . "}";
    } else {
    $outsofar.="\\x{" . $decis . "}";
    }
    } else {
    $outsofar.="\\x{" . dechex($decis) . "}";
    }
    $outsofar.=substr($outs[$ivx],strlen($decis . ';'));
    }
    }
    $labbit=$emojilabbit;
    $perlemoji="perl -e 'binmode(STDOUT, \":utf8\"); print \"" . str_replace("\n", "\x{000A}", $outsofar) . '";' . "' | ";
    }
    if (strpos(str_replace('+',' ',urldecode($_GET['text'])), "\\") !== false) {
    if ($perlemoji == '') { $labbit='"$(cat /tmp/imagerequest_' . server_remote_addr() . '-0.txt | ' . " sed '/\\\\/s//\\\\\\\\/g')" . '" '; }
    //file_put_contents('/tmp/imag.cmd', 'convert -background "' . $bcol . '" -fill "' . $fcol . '" -size ' . $wdt . 'x' . $hgt . ' -font ' . $fnt . ' -pointsize ' . $psiz . ' label:"$(cat /tmp/imagerequest_' . server_remote_addr() . '-0.txt | ' . " sed '/\\\\/s//\\\\\\\\/g')" . '" ' . $slidename . ' ; chmod 777 ' . $slidename);
    exec($perlemoji . 'convert -background "' . $bcol . '" -fill "' . $fcol . '" -size ' . $wdt . 'x' . $hgt . ' -font ' . $fnt . ' -pointsize ' . $psiz . ' label:' . $labbit . ' ' . $slidename);
    exec('chmod 777 ' . $slidename);
    } else {
    if ($perlemoji == '') { $labbit='"$(cat /tmp/imagerequest_' . server_remote_addr() . '-0.txt)' . '" '; }
    exec($perlemoji . 'convert -background "' . $bcol . '" -fill "' . $fcol . '" -size ' . $wdt . 'x' . $hgt . ' -font ' . $fnt . ' -pointsize ' . $psiz . ' label:' . $labbit . ' ' . $slidename);
    exec('chmod 777 ' . $slidename);
    }
    if (isset($_GET['raw'])) {
    header('Content-Type: image/' . $iex);
    echo file_get_contents($slidename);
    unlink($slidename);
    unlink('/tmp/imagerequest_' . server_remote_addr() . '-0.txt');
    exit;
    } else {
    echo "<html>
    <body onload=\"
    if (window.parent != window.self) {
    var cnvs=parent.document.getElementsByTagName('canvas');
    if (eval('' + cnvs.length) > 0) {
    var imgsis=new Image();
    imgsis.onload=function(event){
    var canvasis=cnvs[0];
    var cntxis=canvasis.getContext('2d');
    cntxis.drawImage(event.target, 0, 0);
    };
    imgsis.src='data:image/" . $iex . ";base64," . base64_encode(file_get_contents($slidename)) . "';
    } else {
    var imgs=parent.document.getElementsByTagName('img');
    if (eval('' + imgs.length) > 0) {
    imgs[0].src='data:image/" . $iex . ";base64," . base64_encode(file_get_contents($slidename)) . "';
    } else if (document.body.innerHTML == '') {
    document.body.innerHTML='<img src=data:image/" . $iex . ";base64," . base64_encode(file_get_contents($slidename)) . "></img><style> * { margin:0 0 0 0; padding:0 0 0 0; } img { border-top: 8px solid " . $bcol . "; }</style>';
    } else {
    document.body.innerHTML+='<br><img src=data:image/" . $iex . ";base64," . base64_encode(file_get_contents($slidename)) . "></img>';
    }
    }
    } else if (document.body.innerHTML == '') {
    document.body.innerHTML='<img src=data:image/" . $iex . ";base64," . base64_encode(file_get_contents($slidename)) . "></img><style> * { margin:0 0 0 0; padding:0 0 0 0; } img { border-top: 8px solid " . $bcol . "; }</style>';
    } else {
    document.body.innerHTML+='<br><img src=data:image/" . $iex . ";base64," . base64_encode(file_get_contents($slidename)) . "></img>';
    }
    \"></body></html>";
    unlink('/tmp/imagerequest_' . server_remote_addr() . '-0.txt');
    try {
    unlink($slidename);
    } catch(Exception $esdw) { }
    }
    exit;
    }

    ?>


    Previous relevant Python Cowsay API Cartoon Speech Content Tutorial is shown below.

    Python Cowsay API Cartoon Speech Content Tutorial

    Python Cowsay API Cartoon Speech Content Tutorial

    If you were to ask most people what is more onerous filling in online web forms on the way to making something happen …

    • we’re guessing, rather than saying button presses …
    • we’re guessing, they’re more likely to say typing out text …

    … with it’s associated tabbing out to negotiate as well. But, supposing we could offer you a “speech to text” approach to performing “typing out text” in our latest cowsay Python API / Command-line tool interfacing PHP web application?

    For some years now, we’ve interfaced to a …

    • non-mobile
    • Google Chrome
    • secure URL via https: protocol
    • allowing access to microphone

    … means by which we normally access via a “top” hierarchy level call to our inhouse Google Speech to Text API interfacing web application helper.

    Isn’t a popup window awkward here? Well, you might think so, but today, we discovered with the Google Chrome browser we used on macOS …

    • we initially call our inhouse Google Speech to Text API interfacing web application helper as a popup sitting in front of the cowsay interfacing parent window …
      <?php echo ”

      function anop() {
      if (navigator.userAgent.match(/Android|BlackBerry|iPhone|iPad|iPod|Opera Mini|IEMobile/i)) {
      topwo=window_open('https://www.google.com/intl/en/chrome/demos/speech.html','_blank','top=120,left=' + eval(eval('' + screen.width) - 690) + ',width=690,height=550');
      setTimeout(function(){ topwo.scrollTo(0,0); topwo.document.getElementById('tdm').style.opacity='0.0'; }, 6000);
      setInterval(function(){ if (!topwo.closed) { topwo.focus(); } topwo.location.href='https://www.rjmprogramming.com.au/PHP/speech_supervisor.php?rand=' + Math.floor(Math.random() * 1987967) + '&mode=4'; setTimeout(function(){ topwo.scrollTo(0,0); topwo.document.getElementById('tdm').style.opacity='0.0'; }, 6000); }, 30000);
      } else {
      topwo=window.open('https://www.rjmprogramming.com.au/PHP/speech_supervisor.php?rand=' + Math.floor(Math.random() * 1987967) + '&mode=4','_blank','top=120,left=' + eval(eval('' + screen.width) - 690) + ',width=690,height=550');
      setTimeout(function(){ topwo.scrollTo(0,0); topwo.document.getElementById('tdm').style.opacity='0.0'; }, 6000);
      setInterval(function(){ if (!topwo.closed) { topwo.focus(); } topwo.location.href='https://www.rjmprogramming.com.au/PHP/speech_supervisor.php?rand=' + Math.floor(Math.random() * 1987967) + '&mode=4'; setTimeout(function(){ topwo.scrollTo(0,0); topwo.document.getElementById('tdm').style.opacity='0.0'; }, 6000); }, 30000);
      }
      }

      “; ?>
    • and found that it was visible until any click or focus back to the cowsay interfacing parent window … normally an annoyance …
    • but not if …
      1. we semi regularly reload the our inhouse Google Speech to Text API interfacing web application helper … to refresh it’s red “recording” button instigation … and then …
      2. even if it remains hidden, it is still apparent to the focussed cowsay interfacing parent window on account of an orange “microphone on recording” icon appearing for the Google Chrome web browser user up at it’s Menu Bar … and …
      3. audio being “sight independent” the user does not have to refocus our inhouse Google Speech to Text API interfacing web application helper, just talk into the microphone just after that new icon appears … so that …
      4. the Google Speech to Text smarts help transfer that resultant text over to the textarea of the cowsay interfacing parent window, even avoiding any need to tab out of that textarea element … ahead of …
      5. the rest of the dropdown selections and button presses needed to achieve the user aim of establishing a new slide, perhaps for a Cartoon being created

    … you can see happening with today’s animated GIF presentation on top of the work of yesterday’s Python Cowsay API Cartoon Tutorial in our changed “fourth draft” Cartoon creation and email sharing capable PHP web application you can also try below.


    Previous relevant Python Cowsay API Cartoon Tutorial is shown below.

    Python Cowsay API Cartoon Tutorial

    Python Cowsay API Cartoon Tutorial

    We’ve long been interested in online web application ideas that end up with a half decent cartoon the user can create, and share, themselves. “Half decent” becomes “fully decent” with a user who has a great imagination. And so, onto yesterday’s Python Cowsay API Primer Tutorial‘s start with interfacing to the great cowsay Python API / Command-line tool we access via the PHP exec method conduit to our AlmaLinux Apache/PHP/MySql Linux web server, today we’ve extended that …

    • “proof of concept” thinking … onto …
    • cartoon creation “smarts” … starting with (also egged on here by mobile platform problems with monospaced fonts, it seems like)
    • allowing a tabular display of our cowsay components … into …
    • table cells horizontally aligned (and so, less vulnerable to monospacing inaccuracies) … also allowing …
    • within any table cell there is a topmost th table cell wording part above a cowsay character td cell lower part …
    • “half decent” looking via static CSS
      <?php echo ”

      <style>
      margin: 0 0 0 0;
      padding: 0 0 0 0;
      tr { vertical-align: top; }
      td { vertical-align: top; }
      th { vertical-align: top; }

      * { font-family:'Courier New',Courier,monospace; }
      .img-hor { // thanks to https://stackoverflow.com/questions/32875695/flip-mirror-an-image-horizontally-vertically-with-css
      -moz-transform: scaleX(-1);
      -o-transform: scaleX(-1);
      -webkit-transform: scaleX(-1);
      transform: scaleX(-1);
      filter: FlipH;
      -ms-filter: 'FlipH';
      }
      .img-ver { // thanks to https://stackoverflow.com/questions/32875695/flip-mirror-an-image-horizontally-vertically-with-css
      -moz-transform: scaleY(-1);
      -o-transform: scaleY(-1);
      -webkit-transform: scaleY(-1);
      transform: scaleY(-1);
      filter: FlipV;
      -ms-filter: 'FlipV';
      }

      .glow {
      -webkit-animation: glow 1s linear infinite alternate;
      -moz-animation: glow 1s linear infinite alternate;
      animation: glow 1s linear infinite alternate;
      }

      /* Thanks to https://www.w3schools.com/howto/tryit.asp?filename=tryhow_css_glowing_text */

      @-webkit-keyframes glow {
      from {
      box-shadow: 0 0 3px #fff, 0 0 5px #fff, 0 0 37px #e60073, 0 0 9px #e60073, 0 0 11px #e60073, 0 0 13px #e60073, 0 0 15px #e60073;
      }

      to {
      box-shadow: 0 0 24px #fff, 0 0 6px #ff4da6, 0 0 8px #ff4da6, 0 0 10px #ff4da6, 0 0 12px #ff4da6, 0 0 14px #ff4da6, 0 0 16px #ff4da6;
      }
      }

      th[id$='0'] {
      background: rgba(224,240,240,0.6); //#e0f0f0;
      }

      th[id$='1'] {
      background: rgba(225,241,241,0.6); //#e1f1f1;
      }

      th[id$='2'] {
      background: rgba(226,242,242,0.6); //#e2f2f2;
      }

      th[id$='3'] {
      background: rgba(227,243,243,0.6); //#e3f3f3;
      }

      th[id$='4'] {
      background: rgba(228,244,244,0.6); //#e4f4f4;
      }

      th[id$='5'] {
      background: rgba(229,245,245,0.6); //#e5f5f5;
      }

      th[id$='6'] {
      background: rgba(230,246,246,0.6); //#e6f6f6;
      }

      th[id$='7'] {
      background: rgba(231,247,247,0.6); //#e7f7f7;
      }

      th[id$='8'] {
      background: rgba(232,248,248,0.6); //#e2f2f2;
      }

      th[id$='9'] {
      background: rgba(233,249,249,0.6); //#e9f9f9;
      }

      td[id$='0'] {
      background: rgba(240,240,240,0.3); //#f0f0f0;
      text-shadow:-1px 1px 1px #ff2d90;
      }

      td[id$='1'] {
      background: rgba(241,241,241,0.3); //#f1f1f1;
      text-shadow:-1px 1px 1px #ff2d91;
      float: bottom;
      }

      td[id$='2'] {
      background: rgba(242,242,242,0.3); //#f2f2f2;
      text-shadow:-1px 1px 1px #ff2d92;
      }

      td[id$='3'] {
      background: rgba(243,243,243,0.3); //#f3f3f3;
      text-shadow:-1px 1px 1px #ff2d93;
      }

      td[id$='4'] {
      background: rgba(244,244,244,0.3); //#f4f4f4;
      text-shadow:-1px 1px 1px #ff2d94;
      }

      td[id$='5'] {
      background: rgba(245,245,245,0.3); //#f5f5f5;
      text-shadow:-1px 1px 1px #ff2d95;
      }

      td[id$='6'] {
      background: rgba(246,246,246,0.3); //#f6f6f6;
      text-shadow:-1px 1px 1px #ff2d96;
      }

      td[id$='7'] {
      background: rgba(247,247,247,0.3); //#f7f7f7;
      text-shadow:-1px 1px 1px #ff2d97;
      }

      td[id$='8'] {
      background: rgba(248,248,248,0.3); //#f8f8f8;
      text-shadow:-1px 1px 1px #ff2d98;
      }

      td[id$='9'] {
      background: rgba(249,249,249,0.3); //#f9f9f9;
      text-shadow:-1px 1px 1px #ff2d99;
      }

      table tbody tr:first-child {
      background: transparent; //#f6f6e6;
      }
      </style>

      “; ?>
      … and then …
    • whenever new cell content happens padding-top adding CSS Javascript DOM nuanced display logic via …
      <?php echo ”

      function paddingtopit() {
      var maxtwo=0, thistwo=0;
      var thhs=[], tdhs=[], it=0;
      var thdids=[];
      //trthtd1
      //trtdtd1
      var tds=document.getElementsByTagName('td');
      for (it=0; it<tds.length; it++) {
      if (('' + tds[it].id).indexOf('trtdtd') != -1) {
      if (('' + tds[it].style.paddingTop).replace(/^null/g,'').replace(/^undefined/g,'').trim() != '') {
      tds[it].style.paddingTop='0px';
      }
      }
      }
      for (it=0; it<tds.length; it++) {
      if (('' + tds[it].id).indexOf('trtdtd') != -1) {
      tdhs.push(eval('' + tds[it].getBoundingClientRect().height));
      thdids.push('' + tds[it].id);
      }
      }
      var ths=document.getElementsByTagName('th');
      for (it=0; it<ths.length; it++) {
      if (('' + ths[it].id).indexOf('trthtd') != -1) {
      thhs.push(eval('' + ths[it].getBoundingClientRect().height));
      thistwo=eval(thhs[it] + tdhs[it]);
      if (thistwo > maxtwo) { maxtwo=thistwo; }
      }
      }
      for (it=0; it<tdhs.length; it++) {
      thistwo=eval(thhs[it] + tdhs[it]);
      if (thistwo < maxtwo) {
      document.getElementById(thdids[it]).style.paddingTop='' + eval(maxtwo - thistwo) + 'px';
      }
      }
      }

      “; ?>
      … so that …
    • cartoons present with “speech bubble” wording aligned to the top in our “cells” (ie. th contenteditable=true editable wording on top of td horizontal flip (double click) and/or vertical flop (right click) editable lower part) with those characters aligned to the bottom

    … in our changed “third draft” Cartoon creation and email sharing capable PHP web application you can also try below.


    Previous relevant Python Cowsay API Primer Tutorial is shown below.

    Python Cowsay API Primer Tutorial

    Python Cowsay API Primer Tutorial

    We discovered an interesting Open Source Python API / Command-line tool called cowsay which we installed up at our AlmaLinux web server via …


    pip install cowsay

    … with an integration purpose in mind, so thanks. Before many readers’ time indeed, but some may remember those cute banner printouts that told you who owned the next printout on a spooling “crude graphics” printout in the late 70’s … well cowsay encapsulates those heady days (and who can forget punch cards)?! Before integration, though, we want to test it via a new PHP supervisor on exec method Linux command line interfacings to cowsay.

    So we started, with this “first draft” getting places and then this “second draft” with a little more sophistication to leave the day with this interfacer

    If this was interesting you may be interested in this too.


    If this was interesting you may be interested in this too.


    If this was interesting you may be interested in this too.


    If this was interesting you may be interested in this too.


    If this was interesting you may be interested in this too.


    If this was interesting you may be interested in this too.

    Posted in eLearning, Event-Driven Programming, Tutorials | Tagged , , , , , , , , , , , , , , , , , | Leave a comment

    Image Conversions via PHP GD URL Tutorial

    Image Conversions via PHP GD URL Tutorial

    Image Conversions via PHP GD URL Tutorial

    The PHP inhouse Image Converter web application last talked about at Image Conversions via PHP GD Overlay Reveal Tutorial got a revisit today. It’s been more than two years, and that amount of separation sometimes gives you the chance to “go back to square one” and not be caught in amongst the “labyrinth of thought” as you get too far into complex optional logics you might apply to a web application project.

    And what stood out to us, on this revisit? It was the image input options that immediately stuck out to us, in that it used to be limited to …

    • relative URLs (to the RJM Programming domain) … and we see why we may have left this like this … we wanted to allow for image file specifications … something quite involved (but might be contemplated in a reduced functionality sense into the future …) regarding the first of two new URL modus operandi additions to functionality, those being …
    • absolute URL single image file … and …
    • image data URI single image

    Of course, should the absolute URL web servers allow such access, this opens up whole new vistas of functionality possibility here.

    Both new URL modus operandi above used an HTML iframe (shown along with an HTML form referenced later, also) …

    <?php echo ”

    <iframe style=display:none; id=ifi name=ifi src=./convert_wildcard.php></iframe>
    <form method=POST action='/convert_wildcard.php' target=ifi style=display:none;>
    <input type=hidden name=absimg id=absimg value=''></input><input id=sabsi type=submit value=Submit style=display:none;></input></form>

    “; ?>

    … but in two interestingly different ways … well, you had to be there!

    absolute URL single image file
    <?php echo ”

    function lookforabsolute(ino) {
    if (ino.value.indexOf('data:') == 0 && ino.value.indexOf('image/') != -1) {
    document.getElementById('absimg').value=ino.value;
    document.getElementById('sabsi').click();
    } else if (ino.value.indexOf('//') != -1) {
    ino.title=ino.value;
    document.getElementById('ifi').src='./convert_wildcard.php?absimg=' + encodeURIComponent('http://' + ino.value.split('//')[1]);
    }

    }

    “; ?>
    … meeting up with receiving PHP logic, skeletally …
    <?php

    $gabsimg='';
    if (isset($_GET['absimg'])) {
    $gabsimg=$_GET['absimg'];
    }
    if (isset($_POST['absimg'])) {
    // Perform necessary $_POST scenario populating of $gabsimg
    }
    if ($gabsimg != '') { //isset($_GET['absimg'])) {
    // Perform necessary image URL processing here adjusting parent.document.getElementById('ispec') in the process
    }

    ?>
    image data URI single image
    <?php echo ”

    function lookforabsolute(ino) {
    if (ino.value.indexOf('data:') == 0 && ino.value.indexOf('image/') != -1) {
    document.getElementById('absimg').value=ino.value;
    document.getElementById('sabsi').click();
    }
    else if (ino.value.indexOf('//') != -1) {
    ino.title=ino.value;
    document.getElementById('ifi').src='./convert_wildcard.php?absimg=' + encodeURIComponent('http://' + ino.value.split('//')[1]);
    }
    }

    “; ?>
    … meeting up with receiving PHP logic, skeletally …
    <?php

    $gabsimg='';
    if (isset($_GET['absimg'])) {
    // Perform necessary $_GET scenario populating of $gabsimg
    }
    if (isset($_POST['absimg'])) {
    $gabsimg=$_POST['absimg'];
    if (strpos(('~' . $gabsimg), '~data') !== false) {
    $dcont=str_replace(' ','+',urldecode($gabsimg));
    if (strpos($dcont, 'image/') !== false && strpos($dcont, ';base64,') !== false) {
    $inext=strtolower(explode(';base64,', explode('image/', $dcont)[1])[0]);
    $imgname='/tmp/mycw_' . server_remote_addr() . '.' . $inext;
    file_put_contents($imgname, base64_decode(explode(';base64,', $dcont)[1]));
    echo '<html><body onload=" parent.document.getElementById(' . "'ispec'" . ').value=' . "'" . $imgname . "'" . '; parent.document.getElementById(' . "'ispec'" . ').title=' . "''" . '; "></body></html>';
    exit;
    }
    }
    }
    if ($gabsimg != '') { //isset($_GET['absimg'])) {
    // Perform necessary image URL processing here adjusting parent.document.getElementById('ispec') in the process, if not already done above (and not getting here)
    }

    ?>

    … the most obvious reason for divergent approaches happening here being that data URIs are large and need $_POST[] form navigation while absolute URLs are short enough to use the simpler $_GET[] approach in the changed convert_wildcard.php‘s image conversion PHP web application.

    Did you know?

    Are you interested in the image data of a particular date at this WordPress Blog? Maybe you want to apply some GD filtering to it, download it, and move on? We don’t mind such image data repurposing. Well, for the example date 19th February, 2025 (ie. 20250219) you could …

    … readying you for your PHP GD based filtering “smarts” to apply, and process, and download … etcetera etcetera etcetera.


    Previous relevant Image Conversions via PHP GD Overlay Reveal Tutorial is shown below.

    Image Conversions via PHP GD Overlay Reveal Tutorial

    Image Conversions via PHP GD Overlay Reveal Tutorial

    Around here, we have two words we like to approach the topic of “web design”, where it meets “practicality”, with …

    And so, onto yesterday’s Image Conversions via PHP GD Multiple Actions Tutorial‘s progress with our Image Conversions via PHP GD web application we were keen to think that an “overlay” concept could be part of the workings, at the image creation stage of the web design. Supposing you have a set of images that go to make up the whole, we can use the new “Merge” option as per …

    Show me “Merge” Image Conversion “Overlay” Idea below …


    … we found was most feasible with PNG input image files, with transparency.

    And then, onto yesterday’s Image Conversions via PHP GD Multiple Actions Tutorial‘s progress with our Image Conversions via PHP GD web application we were keen to think that an “reveal” concept (a bit like a cartoon, perhaps) could be part of the workings, at the image creation stage of the web design. Supposing you have a set of images that go to make up the whole, we can use the new “Merge” option as per …

    Show me “Merge” Image Conversion “Reveal” Idea below …


    … we found was most feasible with …

    • PNG input image file(s) … self made or source from a free source such as Pixabay, thanks
    • cut up via Gimp‘s …
      1. Selection Tools -> Free Select … and …
      2. Edit -> Clear … and …
      3. File -> Export As… -> .png (set “Save color values from Transparent Pixels” on)
    • open PNG in Paintbrush and File -> Save As… -> JPEG
    • use “Merge” option of Image Conversion via GD web application

    And then, at least with our MAMP local Apache web server PHP version we can also offer …

    • crop … nominate a colour in images to crop via, and gets a look in with today’s animated GIF tutorial picture
    • transparent … nominate a colour in images to make transparent

    … additional functionalities in the changed convert_wildcard.php‘s image conversion PHP web application.


    Previous relevant Image Conversions via PHP GD Multiple Actions Tutorial is shown below.

    Image Conversions via PHP GD Multiple Actions Tutorial

    Image Conversions via PHP GD Multiple Actions Tutorial

    We’ve waited a while preparing for today’s release of “multiple actions” functionality onto yesterday’s Image Conversions via PHP GD Transformations Tutorial. From how we see it we had a choice of two approaches to delivering this new functionality …

    • start using select (ie. dropdown) element multiple attribute approach … but, especially because we are separating GD “Filters” into one dropdown and “Transformations” into another, we think it would be better to …
    • start prefixing ✔ (&#10004; tick) emoji to selected action(s) to apply to any images involved in the conversions

    The ✔ (&#10004; tick) emoji was enough for us, yet we wanted to indicate to the user the order of actions they’ve entered. To do this we were helped out by Javascript sort methodology used in …

    <?php echo ”

    function sortsel(insel) {
    var sv=insel.value;
    var optsa=insel.innerHTML.split('</option>');
    var sopta=optsa.sort();
    var newih='';
    for (var ioj=0; ioj<sopta.length; ioj++) {
    newih+=sopta[ioj] + '</option>';
    }
    insel.innerHTML=newih;
    insel.value=sv;
    }

    “; ?>

    … accepting the GD “Filter” dropdown object as a parameter. But how is that going to help when “action” titles will just determine the sort order? Well, the select (ie. dropdown) element here is made up of …

    <?php echo ”

    <option value=\”action_desc\”>Action Desc</option>

    “; ?>

    … parts where we started defining the first two this way

    <?php echo ”

    <option class=\”opt000\” value=\”\”>Image Filter …</option><option class=\”opt001\” value=\” \”>Image Filter Ask Arguments …</option>

    “; ?>

    … and then changed our dropdown onchange event logic supplementing a new “whenmulti” total picture data member that is now maintained …

    <?php echo ”

    var nextcls=2;

    function zoomsame(tvo, tvv) {
    var tv=tvo.value;
    var rest='';
    var getcls='';
    if (tvv != '') { tv=tvv; }
    var pa=null;
    if (tv.trim() == '' && ('' + tv.length) != '0') { aska=true; }
    if (tv.trim() != '') {
    if (document.getElementById('whenmulti').value.indexOf(tv + '=') != -1) {
    rest=tv + '=' + document.getElementById('whenmulti').value.split(tv + '=')[1].split(';')[0];
    if (document.getElementById('whenmulti').value.indexOf(rest + ';') != -1) { rest+=';'; }
    document.getElementById('whenmulti').value=document.getElementById('whenmulti').value.replace(rest, '');
    if (document.getElementById('whenmulti').value != '') {
    tvo.name=document.getElementById('whenmulti').value.split('=')[0];
    } else {
    tvo.name='sfilter';
    }
    tvo.innerHTML=tvo.innerHTML.replace(' value=\"' + tv + '\">' + tvo.innerHTML.split(' value=\"' + tv + '\">')[1].split(' ')[0] + ' ', ' value=\"' + tv + '\">');
    getcls=tvo.innerHTML.split(' value=\"' + tv + '\">')[0].split(' class=\"')[eval(-1 + tvo.innerHTML.split(' value=\"' + tv + '\">')[0].split(' class=\"').length)].split('\"')[0];
    if (getcls != '') { tvo.innerHTML=tvo.innerHTML.replace(' class=\"' + getcls + '\"', ''); }
    return '';
    }
    if (tvo.outerHTML.indexOf(' name=') == -1) { tvo.name=tv.trim(); } else if (('' + tvo.name) == 'sfilter') { tvo.name=tv.trim(); }

    if (aska && askastr.indexOf(';' + tv.trim().toLowerCase() + ';') != -1) {
    pa=prompt('Optionally enter argument(s) for ' + tv.trim(), askastr.split(';' + tv.trim().toLowerCase() + ';')[1].split(';')[0]);
    if (pa != null) {
    if (pa.trim() == '') { pa=null; }
    }
    }
    if (pa != null) {
    if (document.getElementById('whenmulti').value == '') {
    document.getElementById('whenmulti').value=tv + '=' + pa;
    } else {
    document.getElementById('whenmulti').value+=';' + tv + '=' + pa;
    document.getElementById('presub').innerHTML+='<input type=hidden name=' + tv.trim() + ' value=></input>';
    }

    if (('' + pa.split(',').length) == '3') {
    document.getElementById('rotation').name='args';
    document.getElementById('rotation').value=pa;
    } else {
    document.getElementById('rotation').name='arg1';
    document.getElementById('rotation').value=pa;
    }
    tvo.innerHTML=tvo.innerHTML.replace(' value=\"' + tv + '\">', ' class=\"opt' + ('00' + nextcls).slice(-3) + '\" value=\"' + tv + '\">&#10004; ');
    nextcls++;
    sortsel(tvo);

    } else {
    if (document.getElementById('whenmulti').value == '') {
    document.getElementById('whenmulti').value=tv + '=' + '';
    } else {
    document.getElementById('whenmulti').value+=';' + tv + '=' + '';
    document.getElementById('presub').innerHTML+='<input type=hidden name=' + tv.trim() + ' value=></input>';
    }
    tvo.innerHTML=tvo.innerHTML.replace(' value=\"' + tv + '\">', ' class=\"opt' + ('00' + nextcls).slice(-3) + '\" value=\"' + tv + '\">&#10004; ');
    nextcls++;

    document.getElementById('rotation').name='rotation';
    document.getElementById('rotation').value='' + document.getElementById('trot').value;
    sortsel(tvo);
    }
    if (tv.trim().toLowerCase() == 'redo') {
    redo();
    } //alert(11);
    //}
    }
    }

    “; ?>

    … helping out that Javascript sort with disruptive, but useful, class attribute inclusion into those option subelement outerHTML (which makes up the select element innerHTML) content in the changed convert_wildcard.php‘s image conversion PHP web application.


    Previous relevant Image Conversions via PHP GD Transformations Tutorial is shown below.

    Image Conversions via PHP GD Transformations Tutorial

    Image Conversions via PHP GD Transformations Tutorial

    In today’s work progressing yesterday’s Image Conversions via PHP GD Command Line Tutorial‘s outcomes …

    • we add into the GD “Filtering” thinking, some “Transformations” …

      … thinking and functionality … and then …
    • we cater for a “curl” mode of use … by, up in that top newish block of code “recreating” a non-existant $argv[] and $argc to precede any “command line” code that fills in $_POST[] array to join in with “surfing the web” mode of use …
      <?php

      $beginswitch=false;
      $nextquality=false;
      $argnext=false;
      $results="";
      $curlstr="";
      $iscurl=false;

      if (!isset($argc) && isset($_GET['command'])) { // curl mode of use eg. curl "ht
      tp://localhost:8888/convert_wildcard.php?command=x*.jpg+-q+76+-negate+.jpeg"
      $curlstr="convert_wildcard.php " . str_replace('+',' ',urldecode($_GET['command']));
      $argv=explode(" ", $curlstr);
      $argc=sizeof($argv);
      if (strpos(strtolower($_SERVER['SERVER_NAME']), 'rjmprogramming.com.au') !== false) { $iscurl=true; }
      }


      if (isset($argc)) { // command line mode of use eg. php convert_wildcard.php x*.jpg -q 76 -negate .jpeg
      $results="\n";
      for ($ii=1; $ii<$argc; $ii++) { if (trim($argv[$ii]) != '') { if ($nextquality) { $nextquality=false; $_POST['quality']=str_replace('%','',$argv[$ii]); } else if (strpos($argv[$ii], '-quality') !== false || strpos($argv[$ii], '-QUALITY') !== false) { $beginswitch=true; if (strpos($argv[$ii],'=') !== false) { $_POST['quality']=str_replace('%','',explode('=', $argv[$ii])[1]); } else if (strlen($argv[$ii]) > 8) {
      $_POST['quality']=str_replace('%','',substr($argv[$ii], 8));
      } else {
      $nextquality=true;
      }
      } else if (strpos($argv[$ii], '-q') !== false || strpos($argv[$ii], '-Q') !== false) {
      $beginswitch=true;
      if (strpos($argv[$ii],'=') !== false) {
      $_POST['quality']=str_replace('%','',explode('=', $argv[$ii])[1]);
      } else if (strlen($argv[$ii]) > 2) {
      $_POST['quality']=str_replace('%','',substr($argv[$ii], 2));
      } else {
      $nextquality=true;
      }
      } else if (substr($argv[$ii],0,1) == '-') {
      $beginswitch=true;
      if (strpos($argv[$ii],'=') !== false) {
      $_POST[substr(strtolower(explode('=',$argv[$ii])[0]),1)]='';
      if (sizeof(explode(',',explode('=',$argv[$ii])[1])) == 3) {
      $_POST['args']=explode('=',$argv[$ii])[1];
      } else {
      $_POST['arg1']=explode('=',$argv[$ii])[1];
      }
      } else {
      $_POST[substr(strtolower(explode('=',$argv[$ii])[0]),1)]='';
      $argnext=true;
      }
      } else if (!isset($_POST['ispec'])) {
      $_POST['ispec']=$argv[$ii];
      } else if (!$beginswitch) {
      $_POST['ispec'].="," . $argv[$ii];
      } else if (substr($argv[$ii],0,1) == '.' || strlen($argv[$ii]) == 3) {
      $argnext=false;
      $_POST['outext']=str_replace("..", ".", "." . $argv[$ii]);
      } else if ($argnext) {
      $argnext=false;
      if (sizeof(explode(',',$argv[$ii])) == 3) {
      $_POST['args']=$argv[$ii];
      } else {
      $_POST['arg1']=$argv[$ii];
      }
      }
      }
      }
      }

      ?>
      … and then rearranged (where first blue section just used to be echo ) the last bit of PHP code …
      <?php

      if (isset($argc) && !$iscurl) {
      echo openthese($results);
      } else {
      $htmlis=
      "<!doctyle html>
      <html>
      <head>
      <title>Image Conversions via PHP GD - RJM Programming - October, 2022</title>
      ... etcetera etcetera etcetera ...
      <select id=extsel style=display:none; id=xxxoutext><option value=''>Enter output relative image file extension [.jpeg]</option><option value=.jpeg>.jpeg</option><option value=.jpg>.jpg</option><option value=.png>.png</option><option value=.gif>.gif</option><option value=.JPEG>.JPEG</option><option value=.JPG>.JPG</option><option value=.PNG>.PNG</option><option value=.GIF>.GIF</option></select>
      </body>
      </html>";
      if (!$iscurl) {
      echo $htmlis;
      } else {
      $phtmlis="temphtml.html";
      while (file_exists($phtmlis)) {
      $phtmlis=str_replace(".htm", "0.htm", $phtmlis);
      }
      file_put_contents($phtmlis, $htmlis);
      //exec("cd " . dirname(__FILE__) . " ; open " . $phtmlis); // . " ; rm -f " . $phtmlis);
      echo "Please issue command ...\nopen http://www.rjmprogramming.com.au/" . $phtmlis . " \n ... to see results. Omit the open word for Windows. You have up to the next minute to do this. ";
      }
      }


      ?>
      … making a MAMP curl usage such as …

      curl "http://localhost:8888/convert_wildcard.php?command=x*.jpg+-q+76+-negate+.jpeg"

      … open the images in your default desktop image editor, while an RJM Programming incarnation such as …

      curl "http://www.rjmprogramming.com.au/convert_wildcard.php?command=wh*.*g*+-q+76+-negate+.jpeg"

      … will return a string such as …

      Please issue command …
      open http://www.rjmprogramming.com.au/temphtml.html
      … to see results. Omit the open word for Windows. You have up to the next minute to do this.

      … and a quick witted user will copy and paste that open http://www.rjmprogramming.com.au/temphtml.html quickly enough to see a webpage offering image download functionalities

    … in the changed convert_wildcard.php‘s image conversion PHP web application.

    Did you know?

    With that last “rjmprogramming.com.au” curl scenario it occurs to us, you could optionally do a multiple command (or use type ahead buffer on Windows) like …


    curl "http://www.rjmprogramming.com.au/convert_wildcard.php?command=wh*.*g*+-q+76+-negate+.jpeg" ; open http://www.rjmprogramming.com.au/temphtml.html

    … for a 99% chance of success without having to worry about the “too quick” copying and pasting in less than a minute caper! Blurb output will correct you if temphtml.html is not the go.

    Or think procedural scripting where Windows has *.bat batch files and macOS or Linux have shells like sh or bash or csh or ksh (our favourite, called Korn Shell). A scheduled procedural crontab command action part could be a Korn Shell one liner like …


    ksh -c 'curl "http://www.rjmprogramming.com.au/convert_wildcard.php?command=wh*.*g*+-q+76+-negate+.jpeg" ; open http://www.rjmprogramming.com.au/temphtml.html'

    Then a Korn Shell script we’ll call “daily.ksh” on macOS or Linux could contain …


    #!/bin/ksh
    curl "http://www.rjmprogramming.com.au/convert_wildcard.php?command=wh*.*g*+-q+76+-negate+.jpeg"
    open http://www.rjmprogramming.com.au/temphtml.html
    exit

    … then, thinking macOS or Linux, make it (perhaps too) executable via


    chmod 777 daily.ksh

    … and make happen via …


    ./daily.ksh


    Previous relevant Image Conversions via PHP GD Command Line Tutorial is shown below.

    Image Conversions via PHP GD Command Line Tutorial

    Image Conversions via PHP GD Command Line Tutorial

    In the online woooooorrrrrlllllddd (of surfing the net in a web browser) we hope you see “nothing to see here” different to yesterday’s Image Conversions via PHP GD Filters Tutorial‘s exploits with our image conversion PHP web application.

    And though this is the boring partner in …

    • must not break previous logics …
    • must work for new functionality

    … adage around here trying to keep “backward compatibility” as you move forward with a project, it is, often, the most important partner.

    As for today, it is more likely our RJM Programming users of the changed convert_wildcard.php will never access our …

    • new command line mode of use … adding to existant …
    • surfing the net (in a web browser) mode of use … and perhaps into the future a …
    • curl mode of use

    … but we think this PHP web application really suits a command line mode of use, given that it so suits a …

    • download to local web server, such as Apache/PHP MAMP environment … and once there …
    • you can control “php” as a command “verb” on the command line (by adding MAMP’s php executable relevant to your version used, to your operating system PATH environment variable), as convenient, to the point that a command line command such as …

      php convert_wildcard.php x*.jpg -q 76 -negate .jpeg

      … reads as a pretty self-explanatory way to achieve a result string such as …


      New image x.jpeg created …
      New image xcode__fibonacci.jpeg created …
      New image xcode_fibonacci.jpeg created …
      New image xcodefibonacci.jpeg created …
      New image xx.jpeg created …

      … as we got on our MAMP environment here

    … paradigm set of conditions, quite like ImageMagick and its command line (“convert” for macOS and Linux and “magick.exe” for Windows) image conversion functionality.

    The PHP changes were 95% a single block of new code, featuring a “first time for us” filling in of $_POST[] array “linkages” to “surfing the net” code in the new “command line” isset($argc) == true mode of use scenario blocks of code, near the top …

    <?php

    $beginswitch=false;
    $nextquality=false;
    $argnext=false;
    $results="";

    if (isset($argc)) { // command line mode of use eg. php convert_wildcard.php x*.jpg -q 76 -negate .jpeg
    $results="\n";
    for ($ii=1; $ii<$argc; $ii++) {
    if (trim($argv[$ii]) != '') {
    if ($nextquality) {
    $nextquality=false;
    $_POST['quality']=str_replace('%','',$argv[$ii]);
    } else if (strpos($argv[$ii], '-quality') !== false || strpos($argv[$ii], '-QUALITY') !== false) {
    $beginswitch=true;
    if (strpos($argv[$ii],'=') !== false) {
    $_POST['quality']=str_replace('%','',explode('=', $argv[$ii])[1]);
    } else if (strlen($argv[$ii]) > 8) {
    $_POST['quality']=str_replace('%','',substr($argv[$ii], 8));
    } else {
    $nextquality=true;
    }
    } else if (strpos($argv[$ii], '-q') !== false || strpos($argv[$ii], '-Q') !== false) {
    $beginswitch=true;
    if (strpos($argv[$ii],'=') !== false) {
    $_POST['quality']=str_replace('%','',explode('=', $argv[$ii])[1]);
    } else if (strlen($argv[$ii]) > 2) {
    $_POST['quality']=str_replace('%','',substr($argv[$ii], 2));
    } else {
    $nextquality=true;
    }
    } else if (substr($argv[$ii],0,1) == '-') {
    $beginswitch=true;
    if (strpos($argv[$ii],'=') !== false) {
    $_POST[substr(strtolower(explode('=',$argv[$ii])[0]),1)]='';
    if (sizeof(explode(',',explode('=',$argv[$ii])[1])) == 3) {
    $_POST['args']=explode('=',$argv[$ii])[1];
    } else {
    $_POST['arg1']=explode('=',$argv[$ii])[1];
    }
    } else {
    $_POST[substr(strtolower(explode('=',$argv[$ii])[0]),1)]='';
    $argnext=true;
    }
    } else if (!isset($_POST['ispec'])) {
    $_POST['ispec']=$argv[$ii];
    } else if (!$beginswitch) {
    $_POST['ispec'].="," . $argv[$ii];
    } else if (substr($argv[$ii],0,1) == '.' || strlen($argv[$ii]) == 3) {
    $argnext=false;
    $_POST['outext']=str_replace("..", ".", "." . $argv[$ii]);
    } else if ($argnext) {
    $argnext=false;
    if (sizeof(explode(',',$argv[$ii])) == 3) {
    $_POST['args']=$argv[$ii];
    } else {
    $_POST['arg1']=$argv[$ii];
    }
    }
    }
    }
    }

    ?>


    Previous relevant Image Conversions via PHP GD Filters Tutorial is shown below.

    Image Conversions via PHP GD Filters Tutorial

    Image Conversions via PHP GD Filters Tutorial

    Once in the (PHP) GD-land of yesterday’s Image Conversions via PHP GD Primer Tutorial, you’d be mad not to facilitate some image filtering which GD is so good at. And so, we have included an optional usage dropdown as per …

    … into the mix. We add this select element “dropdown” within the HTML form method=POST action=”Here’s looking at you kid” arrangement. Initially it gets assigned just an ID attribute, with no NAME attribute, which is an ideal arrangement when functionality is optional. And so, if the user chooses a real “filter” here it gets assigned an appropriate NAME attribute as per the PHP’s Javascript dropdown onchange event logic …

    <?php echo ”

    function zoomsame(tvo) {
    var tv=tvo.value;
    var pa=null;
    if (tv.trim() == '' && ('' + tv.length) != '0') { aska=true; }
    if (tv.trim() != '') {
    tvo.name=tv.trim();
    if (aska && askastr.indexOf(';' + tv.trim().toLowerCase() + ';') != -1) {
    pa=prompt('Optionally enter argument(s) for ' + tv.trim(), askastr.split(';' + tv.trim().toLowerCase() + ';')[1].split(';')[0]);
    if (pa != null) {
    if (pa.trim() == '') { pa=null; }
    }
    }
    if (pa != null) {
    if (('' + pa.split(',').length) == '3') {
    document.getElementById('rotation').name='args';
    document.getElementById('rotation').value=pa;
    } else {
    document.getElementById('rotation').name='arg1';
    document.getElementById('rotation').value=pa;
    }
    } else {
    document.getElementById('rotation').name='rotation';
    document.getElementById('rotation').value='' + document.getElementById('trot').value;
    }
    if (tv.trim().toLowerCase() == 'redo') {
    redo();
    } //alert(11);
    //}
    }
    }

    “; ?>

    … turning a “display useful only” HTML dropdown element into one whose value is transferred with self-navigation to interest the PHP “recall” logic …

    <?php

    function ourimagecreatefromfile($zfilename) {
    global $div_img, $ext;
    //file_put_contents("qwe.qweaa", $zfilename);
    if (isset($_GET['emboss']) || isset($_POST['emboss'])) {
    //file_put_contents("qwe.qwe", str_replace(' ','+',urldecode($_GET['emboss'])) . str_replace(' ','+',urldecode($_POST['emboss'])) . $zfilename);
    //file_put_contents("qwe.qwex", $_SERVER['HTTP_REFERER']);
    $jm_php = imagecreatefromstring(ourfile_get_contents(str_replace(' ','+',urldecode($_GET['emboss'])) . str_replace(' ','+',urldecode($_POST['emboss'])) . $zfilename));
    $emboss = getpostmaybe('arg1',array([-2, -1, 0], [-1, 1, 1], [0, 1, 2]));
    //file_put_contents("qwe.qwexx", $_SERVER['HTTP_REFERER']);
    //imageconvolution($jm_php, $emboss, 1, 0);
    imagefilter($jm_php, IMG_FILTER_EMBOSS);
    return $jm_php; //$new_name = 'anewimage0.jpg';
    $nj=0;
    while (file_exists('anewimage' . $nj . '.jpg')) {
    $nj++;
    $new_name = 'anewimage' . $nj . '.jpg';
    }
    imagejpeg($jm_php, $new_name);
    $qpzm='data:image/jpeg;base64,' . base64_encode(ourfile_get_contents($new_name));
    imagedestroy($jm_php);
    unlink($new_name);
    //file_put_contents("qwe.qwez", $_SERVER['HTTP_REFERER']);
    if (strpos($_SERVER['HTTP_REFERER'], "/pdfimageplustext.php") !== false) {
    //file_put_contents("qwe.qwey", "<!doctype html><html><body onload=\" if (parent.document.getElementById('slideshow')) { parent.document.getElementById('slideshow').value=parent.undobackup('" . datauriit($qpzm) . "'); parent.forcescale(); } \"></body></html>");
    echo "<!doctype html><html><body onload=\" if (parent.document.getElementById('slideshow')) { parent.document.getElementById('slideshow').value=parent.undobackup('" . datauriit($qpzm) . "'); parent.forcescale(); } \"></body></html>";
    exit;
    }
    return $qpzm;
    } else if (isset($_GET['edge']) || isset($_POST['edge'])) {
    $jm_php = imagecreatefromstring(ourfile_get_contents(str_replace(' ','+',urldecode($_GET['edge'])) . str_replace(' ','+',urldecode($_POST['edge'])) . $zfilename));
    $edge_detect = getpostmaybe('arg1',array([-1, -1, -1], [-1, 8, -1], [-1, -1, -1]));
    imageconvolution($jm_php, $edge_detect, 1, 0);
    imageconvolution($jm_php, $edge_detect, 1, 255);
    return $jm_php; //$new_name = 'anewimage0.jpg';
    $nj=0;
    while (file_exists('anewimage' . $nj . '.jpg')) {
    $nj++;
    $new_name = 'anewimage' . $nj . '.jpg';
    }
    imagejpeg($jm_php, $new_name);
    $qpzm='data:image/jpeg;base64,' . base64_encode(ourfile_get_contents($new_name));
    imagedestroy($jm_php);
    unlink($new_name);
    if (strpos($_SERVER['HTTP_REFERER'], "/pdfimageplustext.php") !== false) {
    echo "<!doctype html><html><body onload=\" if (parent.document.getElementById('slideshow')) { parent.document.getElementById('slideshow').value=parent.undobackup('" . datauriit($qpzm) . "'); parent.forcescale(); } \"></body></html>";
    exit;
    }
    return $qpzm;
    } else if (isset($_GET['negedge']) || isset($_POST['negedge'])) {
    $jm_php = imagecreatefromstring(ourfile_get_contents(str_replace(' ','+',urldecode($_GET['negedge'])) . str_replace(' ','+',urldecode($_POST['negedge'])) . $zfilename));
    $edge_detect = getpostmaybe('arg1',array([-1, -1, -1], [-1, 8, -1], [-1, -1, -1]));
    imageconvolution($jm_php, $edge_detect, 1, 0);
    //imageconvolution($jm_php, $edge_detect, 1, 255);
    return $jm_php; //$new_name = 'anewimage0.jpg';
    $nj=0;
    while (file_exists('anewimage' . $nj . '.jpg')) {
    $nj++;
    $new_name = 'anewimage' . $nj . '.jpg';
    }
    imagejpeg($jm_php, $new_name);
    $qpzm='data:image/jpeg;base64,' . base64_encode(ourfile_get_contents($new_name));
    imagedestroy($jm_php);
    unlink($new_name);
    if (strpos($_SERVER['HTTP_REFERER'], "/pdfimageplustext.php") !== false) {
    echo "<!doctype html><html><body onload=\" if (parent.document.getElementById('slideshow')) { parent.document.getElementById('slideshow').value=parent.undobackup('" . datauriit($qpzm) . "'); parent.forcescale(); } \"></body></html>";
    exit;
    }
    return $qpzm;
    } else if (isset($_GET['sharpen']) || isset($_POST['sharpen'])) {
    $jm_php = imagecreatefromstring(ourfile_get_contents(str_replace(' ','+',urldecode($_GET['sharpen'])) . str_replace(' ','+',urldecode($_POST['sharpen'])) . $zfilename));
    $sharpen = getpostmaybe('arg1',array([0, -1, 0], [-1, 5, -1], [0, -1, 0]));
    imageconvolution($jm_php, $sharpen, 1, 0);
    return $jm_php; //$new_name = 'anewimage0.jpg';
    $nj=0;
    while (file_exists('anewimage' . $nj . '.jpg')) {
    $nj++;
    $new_name = 'anewimage' . $nj . '.jpg';
    }
    imagejpeg($jm_php, $new_name);
    $qpzm='data:image/jpeg;base64,' . base64_encode(ourfile_get_contents($new_name));
    imagedestroy($jm_php);
    unlink($new_name);
    if (strpos($_SERVER['HTTP_REFERER'], "/pdfimageplustext.php") !== false) {
    echo "<!doctype html><html><body onload=\" if (parent.document.getElementById('slideshow')) { parent.document.getElementById('slideshow').value=parent.undobackup('" . datauriit($qpzm) . "'); parent.forcescale(); } \"></body></html>";
    exit;
    }
    return $qpzm;
    } else if (isset($_GET['boxblur']) || isset($_POST['boxblur'])) {
    $jm_php = imagecreatefromstring(ourfile_get_contents(str_replace(' ','+',urldecode($_GET['boxblur'])) . str_replace(' ','+',urldecode($_POST['boxblur'])) . $zfilename));
    $box_blur = getpostmaybe('arg1',array([1, 1, 1], [1, 1, 1], [1, 1, 1]));
    imageconvolution($jm_php, $box_blur, 9, 0);
    return $jm_php; //$new_name = 'anewimage0.jpg';
    $nj=0;
    while (file_exists('anewimage' . $nj . '.jpg')) {
    $nj++;
    $new_name = 'anewimage' . $nj . '.jpg';
    }
    imagejpeg($jm_php, $new_name);
    $qpzm='data:image/jpeg;base64,' . base64_encode(ourfile_get_contents($new_name));
    imagedestroy($jm_php);
    unlink($new_name);
    if (strpos($_SERVER['HTTP_REFERER'], "/pdfimageplustext.php") !== false) {
    echo "<!doctype html><html><body onload=\" if (parent.document.getElementById('slideshow')) { parent.document.getElementById('slideshow').value=parent.undobackup('" . datauriit($qpzm) . "'); parent.forcescale(); } \"></body></html>";
    exit;
    }
    return $qpzm;
    } else if (isset($_GET['grayscale']) || isset($_POST['grayscale'])) {
    $jm_php = imagecreatefromstring(ourfile_get_contents(str_replace(' ','+',urldecode($_GET['grayscale'])) . str_replace(' ','+',urldecode($_POST['grayscale'])) . $zfilename));
    imagefilter($jm_php, IMG_FILTER_GRAYSCALE);
    return $jm_php; //$new_name = 'anewimage0.jpg';
    $nj=0;
    while (file_exists('anewimage' . $nj . '.jpg')) {
    $nj++;
    $new_name = 'anewimage' . $nj . '.jpg';
    }
    imagejpeg($jm_php, $new_name);
    $qpzm='data:image/jpeg;base64,' . base64_encode(ourfile_get_contents($new_name));
    imagedestroy($jm_php);
    unlink($new_name);
    if (strpos($_SERVER['HTTP_REFERER'], "/pdfimageplustext.php") !== false) {
    echo "<!doctype html><html><body onload=\" if (parent.document.getElementById('slideshow')) { parent.document.getElementById('slideshow').value=parent.undobackup('" . datauriit($qpzm) . "'); parent.forcescale(); } \"></body></html>";
    exit;
    }
    return $qpzm;
    } else if (isset($_GET['gaussianianblur']) || isset($_POST['gaussianblur'])) {
    $jm_php = imagecreatefromstring(ourfile_get_contents(str_replace(' ','+',urldecode($_GET['gaussianblur'])) . str_replace(' ','+',urldecode($_POST['gaussianblur'])) . $zfilename));
    imagefilter($jm_php, IMG_FILTER_GAUSSIAN_BLUR);
    return $jm_php; //$new_name = 'anewimage0.jpg';
    $nj=0;
    while (file_exists('anewimage' . $nj . '.jpg')) {
    $nj++;
    $new_name = 'anewimage' . $nj . '.jpg';
    }
    imagejpeg($jm_php, $new_name);
    $qpzm='data:image/jpeg;base64,' . base64_encode(ourfile_get_contents($new_name));
    imagedestroy($jm_php);
    unlink($new_name);
    if (strpos($_SERVER['HTTP_REFERER'], "/pdfimageplustext.php") !== false) {
    echo "<!doctype html><html><body onload=\" if (parent.document.getElementById('slideshow')) { parent.document.getElementById('slideshow').value=parent.undobackup('" . datauriit($qpzm) . "'); parent.forcescale(); } \"></body></html>";
    exit;
    }
    return $qpzm;
    } else if (isset($_GET['selectiveblur']) || isset($_POST['selectiveblur'])) {

    $jm_php = imagecreatefromstring(ourfile_get_contents(str_replace(' ','+',urldecode($_GET['selectiveblur'])) . str_replace(' ','+',urldecode($_POST['selectiveblur'])) . $zfilename));
    imagefilter($jm_php, IMG_FILTER_SELECTIVE_BLUR);
    return $jm_php; //$new_name = 'anewimage0.jpg';
    $nj=0;
    while (file_exists('anewimage' . $nj . '.jpg')) {
    $nj++;
    $new_name = 'anewimage' . $nj . '.jpg';
    }
    imagejpeg($jm_php, $new_name);
    $qpzm='data:image/jpeg;base64,' . base64_encode(ourfile_get_contents($new_name));
    imagedestroy($jm_php);
    unlink($new_name);
    if (strpos($_SERVER['HTTP_REFERER'], "/pdfimageplustext.php") !== false) {
    echo "<!doctype html><html><body onload=\" if (parent.document.getElementById('slideshow')) { parent.document.getElementById('slideshow').value=parent.undobackup('" . datauriit($qpzm) . "'); parent.forcescale(); } \"></body></html>";
    exit;
    }
    return $qpzm;

    } else if (isset($_GET['negate']) || isset($_POST['negate'])) {
    $jm_php = imagecreatefromstring(ourfile_get_contents(str_replace(' ','+',urldecode($_GET['negate'])) . str_replace(' ','+',urldecode($_POST['negate'])) . $zfilename));
    imagefilter($jm_php, IMG_FILTER_NEGATE);
    return $jm_php; //$new_name = 'anewimage0.jpg';
    $nj=0;
    while (file_exists('anewimage' . $nj . '.jpg')) {
    $nj++;
    $new_name = 'anewimage' . $nj . '.jpg';
    }
    imagejpeg($jm_php, $new_name);
    $qpzm='data:image/jpeg;base64,' . base64_encode(ourfile_get_contents($new_name));
    imagedestroy($jm_php);
    unlink($new_name);
    if (strpos($_SERVER['HTTP_REFERER'], "/pdfimageplustext.php") !== false) {
    echo "<!doctype html><html><body onload=\" if (parent.document.getElementById('slideshow')) { parent.document.getElementById('slideshow').value=parent.undobackup('" . datauriit($qpzm) . "'); parent.forcescale(); } \"></body></html>";
    exit;
    }
    return $qpzm;
    } else if (isset($_GET['colourizered']) || isset($_POST['colourizered']) || isset($_GET['colorizered']) || isset($_POST['colorizered'])) {
    $jm_php = imagecreatefromstring(ourfile_get_contents(str_replace(' ','+',urldecode($_GET['colourizered'])) . str_replace(' ','+',urldecode($_POST['colourizered'])) . $zfilename));
    imagefilter($jm_php, IMG_FILTER_COLORIZE, getpostmaybe('arg1',rand(0,255)), 0, 0); //, 100);
    return $jm_php; //$new_name = 'anewimage0.jpg';
    $nj=0;
    while (file_exists('anewimage' . $nj . '.jpg')) {
    $nj++;
    $new_name = 'anewimage' . $nj . '.jpg';
    }
    imagejpeg($jm_php, $new_name);
    $qpzm='data:image/jpeg;base64,' . base64_encode(ourfile_get_contents($new_name));
    imagedestroy($jm_php);
    unlink($new_name);
    if (strpos($_SERVER['HTTP_REFERER'], "/pdfimageplustext.php") !== false) {
    echo "<!doctype html><html><body onload=\" if (parent.document.getElementById('slideshow')) { parent.document.getElementById('slideshow').value=parent.undobackup('" . datauriit($qpzm) . "'); parent.forcescale(); } \"></body></html>";
    exit;
    }
    return $qpzm;
    } else if (isset($_GET['colourizegreen']) || isset($_POST['colourizegreen']) || isset($_GET['colorizegreen']) || isset($_POST['colorizegreen'])) {
    $jm_php = imagecreatefromstring(ourfile_get_contents(str_replace(' ','+',urldecode($_GET['colourizegreen'])) . str_replace(' ','+',urldecode($_POST['colourizegreen'])) . $zfilename));
    imagefilter($jm_php, IMG_FILTER_COLORIZE, 0, getpostmaybe('arg1',rand(0,255)), 0); //, 100);
    return $jm_php; //$new_name = 'anewimage0.jpg';
    $nj=0;
    while (file_exists('anewimage' . $nj . '.jpg')) {
    $nj++;
    $new_name = 'anewimage' . $nj . '.jpg';
    }
    imagejpeg($jm_php, $new_name);
    $qpzm='data:image/jpeg;base64,' . base64_encode(ourfile_get_contents($new_name));
    imagedestroy($jm_php);
    unlink($new_name);
    if (strpos($_SERVER['HTTP_REFERER'], "/pdfimageplustext.php") !== false) {
    echo "<!doctype html><html><body onload=\" if (parent.document.getElementById('slideshow')) { parent.document.getElementById('slideshow').value=parent.undobackup('" . datauriit($qpzm) . "'); parent.forcescale(); } \"></body></html>";
    exit;
    }
    return $qpzm;
    } else if (isset($_GET['colourize']) || isset($_POST['colourize']) || isset($_GET['colorize']) || isset($_POST['colorize'])) {
    $jm_php = imagecreatefromstring(ourfile_get_contents(str_replace(' ','+',urldecode($_GET['colourize'])) . str_replace(' ','+',urldecode($_POST['colourize'])) . $zfilename));
    imagefilter($jm_php, IMG_FILTER_COLORIZE, getpostmaybe('arg1',rand(0, 255)), getpostmaybe('arg2',rand(0, 255)), getpostmaybe('arg3',rand(0, 255))); //, 100);
    return $jm_php; //$new_name = 'anewimage0.jpg';
    $nj=0;
    while (file_exists('anewimage' . $nj . '.jpg')) {
    $nj++;
    $new_name = 'anewimage' . $nj . '.jpg';
    }
    imagejpeg($jm_php, $new_name);
    $qpzm='data:image/jpeg;base64,' . base64_encode(ourfile_get_contents($new_name));
    imagedestroy($jm_php);
    unlink($new_name);
    if (strpos($_SERVER['HTTP_REFERER'], "/pdfimageplustext.php") !== false) {
    echo "<!doctype html><html><body onload=\" if (parent.document.getElementById('slideshow')) { parent.document.getElementById('slideshow').value=parent.undobackup('" . datauriit($qpzm) . "'); parent.forcescale(); } \"></body></html>";
    exit;
    }
    return $qpzm;
    } else if (isset($_GET['colourizeblue']) || isset($_POST['colourizeblue']) || isset($_GET['colorizeblue']) || isset($_POST['colorizeblue'])) {
    $jm_php = imagecreatefromstring(ourfile_get_contents(str_replace(' ','+',urldecode($_GET['colourizeblue'])) . str_replace(' ','+',urldecode($_POST['colourizeblue'])) . $zfilename));
    imagefilter($jm_php, IMG_FILTER_COLORIZE, 0, 0, getpostmaybe('arg1',rand(0,255))); //, 100);
    return $jm_php; //$new_name = 'anewimage0.jpg';
    $nj=0;
    while (file_exists('anewimage' . $nj . '.jpg')) {
    $nj++;
    $new_name = 'anewimage' . $nj . '.jpg';
    }
    imagejpeg($jm_php, $new_name);
    $qpzm='data:image/jpeg;base64,' . base64_encode(ourfile_get_contents($new_name));
    imagedestroy($jm_php);
    unlink($new_name);
    if (strpos($_SERVER['HTTP_REFERER'], "/pdfimageplustext.php") !== false) {
    echo "<!doctype html><html><body onload=\" if (parent.document.getElementById('slideshow')) { parent.document.getElementById('slideshow').value=parent.undobackup('" . datauriit($qpzm) . "'); parent.forcescale(); } \"></body></html>";
    exit;
    }
    return $qpzm;
    } else if (isset($_GET['pixellate']) || isset($_POST['pixellate']) || isset($_GET['pixelate']) || isset($_POST['pixelate'])) {
    $jm_php = imagecreatefromstring(ourfile_get_contents(str_replace(' ','+',urldecode($_GET['pixellate'])) . str_replace(' ','+',urldecode($_POST['pixellate'])) . $zfilename));
    imagefilter($jm_php, IMG_FILTER_PIXELATE, getpostmaybe('arg1',rand(1, 9))); // was 3
    return $jm_php; //$new_name = 'anewimage0.jpg';
    $nj=0;
    while (file_exists('anewimage' . $nj . '.jpg')) {
    $nj++;
    $new_name = 'anewimage' . $nj . '.jpg';
    }
    imagejpeg($jm_php, $new_name);
    $qpzm='data:image/jpeg;base64,' . base64_encode(ourfile_get_contents($new_name));
    imagedestroy($jm_php);
    unlink($new_name);
    if (strpos($_SERVER['HTTP_REFERER'], "/pdfimageplustext.php") !== false) {
    echo "<!doctype html><html><body onload=\" if (parent.document.getElementById('slideshow')) { parent.document.getElementById('slideshow').value=parent.undobackup('" . datauriit($qpzm) . "'); parent.forcescale(); } \"></body></html>";
    exit;
    }
    return $qpzm;
    } else if (isset($_GET['smooth']) || isset($_POST['smooth'])) {
    $jm_php = imagecreatefromstring(ourfile_get_contents(str_replace(' ','+',urldecode($_GET['smooth'])) . str_replace(' ','+',urldecode($_POST['smooth'])) . $zfilename));
    imagefilter($jm_php, IMG_FILTER_SMOOTH, getpostmaybe('arg1',rand(5, 35))); // was -1924.124
    return $jm_php; //$new_name = 'anewimage0.jpg';
    $nj=0;
    while (file_exists('anewimage' . $nj . '.jpg')) {
    $nj++;
    $new_name = 'anewimage' . $nj . '.jpg';
    }
    imagejpeg($jm_php, $new_name);
    $qpzm='data:image/jpeg;base64,' . base64_encode(ourfile_get_contents($new_name));
    imagedestroy($jm_php);
    unlink($new_name);
    if (strpos($_SERVER['HTTP_REFERER'], "/pdfimageplustext.php") !== false) {
    echo "<!doctype html><html><body onload=\" if (parent.document.getElementById('slideshow')) { parent.document.getElementById('slideshow').value=parent.undobackup('" . datauriit($qpzm) . "'); parent.forcescale(); } \"></body></html>";
    exit;
    }
    return $qpzm;
    } else if (isset($_GET['contrast']) || isset($_POST['contrast'])) {
    $jm_php = imagecreatefromstring(ourfile_get_contents(str_replace(' ','+',urldecode($_GET['contrast'])) . str_replace(' ','+',urldecode($_POST['contrast'])) . $zfilename));
    imagefilter($jm_php, IMG_FILTER_CONTRAST, getpostmaybe('arg1',rand(-100, 100))); // was -90
    return $jm_php; //$new_name = 'anewimage0.jpg';
    $nj=0;
    while (file_exists('anewimage' . $nj . '.jpg')) {
    $nj++;
    $new_name = 'anewimage' . $nj . '.jpg';
    }
    imagejpeg($jm_php, $new_name);
    $qpzm='data:image/jpeg;base64,' . base64_encode(ourfile_get_contents($new_name));
    imagedestroy($jm_php);
    unlink($new_name);
    if (strpos($_SERVER['HTTP_REFERER'], "/pdfimageplustext.php") !== false) {
    echo "<!doctype html><html><body onload=\" if (parent.document.getElementById('slideshow')) { parent.document.getElementById('slideshow').value=parent.undobackup('" . datauriit($qpzm) . "'); parent.forcescale(); } \"></body></html>";
    exit;
    }
    return $qpzm;
    } else if (isset($_GET['brightness']) || isset($_POST['brightness'])) {
    $jm_php = imagecreatefromstring(ourfile_get_contents(str_replace(' ','+',urldecode($_GET['brightness'])) . str_replace(' ','+',urldecode($_POST['brightness'])) . $zfilename));
    imagefilter($jm_php, IMG_FILTER_BRIGHTNESS, getpostmaybe('arg1',rand(-255, 255))); // was 98
    return $jm_php; //$new_name = 'anewimage0.jpg';
    $nj=0;
    while (file_exists('anewimage' . $nj . '.jpg')) {
    $nj++;
    $new_name = 'anewimage' . $nj . '.jpg';
    }
    imagejpeg($jm_php, $new_name);
    $qpzm='data:image/jpeg;base64,' . base64_encode(ourfile_get_contents($new_name));
    imagedestroy($jm_php);
    unlink($new_name);
    if (strpos($_SERVER['HTTP_REFERER'], "/pdfimageplustext.php") !== false) {
    echo "<!doctype html><html><body onload=\" if (parent.document.getElementById('slideshow')) { parent.document.getElementById('slideshow').value=parent.undobackup('" . datauriit($qpzm) . "'); parent.forcescale(); } \"></body></html>";
    exit;
    }
    return $qpzm;
    } else if (isset($_GET['sketchy']) || isset($_POST['sketchy']) || isset($_GET['mean_removal']) || isset($_POST['mean_removal']) || isset($_GET['mean-removal']) || isset($_POST['mean-removal'])) {
    $jm_php = imagecreatefromstring(ourfile_get_contents(str_replace(' ','+',urldecode($_GET['sketchy'])) . str_replace(' ','+',urldecode($_POST['sketchy'])) . $zfilename));
    imagefilter($jm_php, IMG_FILTER_MEAN_REMOVAL);
    return $jm_php; //$new_name = 'anewimage0.jpg';
    $nj=0;
    while (file_exists('anewimage' . $nj . '.jpg')) {
    $nj++;
    $new_name = 'anewimage' . $nj . '.jpg';
    }
    imagejpeg($jm_php, $new_name);
    $qpzm='data:image/jpeg;base64,' . base64_encode(ourfile_get_contents($new_name));
    imagedestroy($jm_php);
    unlink($new_name);
    if (strpos($_SERVER['HTTP_REFERER'], "/pdfimageplustext.php") !== false) {
    echo "<!doctype html><html><body onload=\" if (parent.document.getElementById('slideshow')) { parent.document.getElementById('slideshow').value=parent.undobackup('" . datauriit($qpzm) . "'); parent.forcescale(); } \"></body></html>";
    exit;
    }
    return $qpzm;
    } else if (isset($_GET['flipvertical']) || isset($_POST['flipvertical'])) {
    $jm_php = imagecreatefromstring(ourfile_get_contents(str_replace(' ','+',urldecode($_GET['flipvertical'])) . str_replace(' ','+',urldecode($_POST['flipvertical'])) . $zfilename));
    $jm_php=ourImageFlip($jm_php, '1'); //imageflip($jm_php, IMG_FLIP_VERTICAL);
    return $jm_php; //$new_name = 'anewimage0.jpg';
    $nj=0;
    while (file_exists('anewimage' . $nj . '.jpg')) {
    $nj++;
    $new_name = 'anewimage' . $nj . '.jpg';
    }
    imagejpeg($jm_php, $new_name);
    $qpzm='data:image/jpeg;base64,' . base64_encode(ourfile_get_contents($new_name));
    imagedestroy($jm_php);
    unlink($new_name);
    if (strpos($_SERVER['HTTP_REFERER'], "/pdfimageplustext.php") !== false) {
    echo "<!doctype html><html><body onload=\" if (parent.document.getElementById('slideshow')) { parent.document.getElementById('slideshow').value=parent.undobackup('" . datauriit($qpzm) . "'); parent.forcescale(); } \"></body></html>";
    exit;
    }
    return $qpzm;
    } else if (isset($_GET['fliphorizontal']) || isset($_POST['fliphorizontal'])) {
    $jm_php = imagecreatefromstring(ourfile_get_contents(str_replace(' ','+',urldecode($_GET['fliphorizontal'])) . str_replace(' ','+',urldecode($_POST['fliphorizontal'])) . $zfilename));
    $jm_php=ourImageFlip($jm_php, '2'); //imageflip($jm_php, IMG_FLIP_HORIZONTAL);
    return $jm_php; //$new_name = 'anewimage0.jpg';
    $nj=0;
    while (file_exists('anewimage' . $nj . '.jpg')) {
    $nj++;
    $new_name = 'anewimage' . $nj . '.jpg';
    }
    imagejpeg($jm_php, $new_name);
    $qpzm='data:image/jpeg;base64,' . base64_encode(ourfile_get_contents($new_name));
    imagedestroy($jm_php);
    unlink($new_name);
    if (strpos($_SERVER['HTTP_REFERER'], "/pdfimageplustext.php") !== false) {
    echo "<!doctype html><html><body onload=\" if (parent.document.getElementById('slideshow')) { parent.document.getElementById('slideshow').value=parent.undobackup('" . datauriit($qpzm) . "'); parent.forcescale(); } \"></body></html>";
    exit;
    }
    return $qpzm;
    } else if (isset($_GET['flip']) || isset($_POST['flip'])) {
    $jm_php = imagecreatefromstring(ourfile_get_contents(str_replace(' ','+',urldecode($_GET['flip'])) . str_replace(' ','+',urldecode($_POST['flip'])) . $zfilename));
    $jm_php=ourImageFlip($jm_php, '3'); //imageflip($jm_php, IMG_FLIP_BOTH);
    return $jm_php; //$new_name = 'anewimage0.jpg';
    $nj=0;
    while (file_exists('anewimage' . $nj . '.jpg')) {
    $nj++;
    $new_name = 'anewimage' . $nj . '.jpg';
    }
    imagejpeg($jm_php, $new_name);
    $qpzm='data:image/jpeg;base64,' . base64_encode(ourfile_get_contents($new_name));
    imagedestroy($jm_php);
    unlink($new_name);
    if (strpos($_SERVER['HTTP_REFERER'], "/pdfimageplustext.php") !== false) {
    echo "<!doctype html><html><body onload=\" if (parent.document.getElementById('slideshow')) { parent.document.getElementById('slideshow').value=parent.undobackup('" . datauriit($qpzm) . "'); parent.forcescale(); } \"></body></html>";
    exit;
    }
    return $qpzm;
    } else if (isset($_GET['rotation']) || isset($_POST['rotation'])) {
    //file_put_contents("qwe.qwe1", $zfilename);
    $jm_php = imagecreatefromstring(ourfile_get_contents(str_replace(' ','+',urldecode($_GET['flip'])) . str_replace(' ','+',urldecode($_POST['flip'])) . $zfilename));
    //file_put_contents("qwe.qwe2", $zfilename);
    if (isset($_GET['rotation'])) {
    $iim_php=imagerotate($jm_php, floatval(trim(str_replace('+',' ',urldecode($_GET['rotation'])))), 0);
    } else if (isset($_POST['rotation'])) {
    //file_put_contents("qwe.qwe3", '' . (trim(str_replace('+',' ',urldecode($_POST['rotation'])))));
    $iim_php=imagerotate($jm_php, floatval(trim(str_replace('+',' ',urldecode($_POST['rotation'])))), 0);
    //file_put_contents("qwe.qwe4", '' . floatval(trim(str_replace('+',' ',urldecode($_POST['rotation'])))));
    } else {
    $iim_php=imagerotate($jm_php, 0.0, 0);
    }
    //file_put_contents("qwe.qwe5", $zfilename);
    return $jm_php; //$new_name = 'anewimage0.jpg';
    $nj=0;
    while (file_exists('anewimage' . $nj . '.jpg')) {
    $nj++;
    $new_name = 'anewimage' . $nj . '.jpg';
    }
    //file_put_contents("qwe.qwe6", $zfilename);
    imagejpeg($iim_php, $new_name);
    //file_put_contents("qwe.qwe7", $zfilename);
    $qpzm='data:image/jpeg;base64,' . base64_encode(ourfile_get_contents($new_name));
    //file_put_contents("qwe.qwe8", $zfilename);
    imagedestroy($jm_php);
    imagedestroy($iim_php);
    //file_put_contents("qwe.qwe9", $zfilename);
    unlink($new_name);
    if (strpos($_SERVER['HTTP_REFERER'], "/pdfimageplustext.php") !== false) {
    echo "<!doctype html><html><body onload=\" if (parent.document.getElementById('slideshow')) { parent.document.getElementById('slideshow').value=parent.undobackup('" . datauriit($qpzm) . "'); parent.forcescale(); } \"></body></html>";
    exit;
    }
    return $qpzm;
    }
    return imagecreatefromstring(file_get_contents($zfilename)); // 'data:image/' . substr($ext,1) . ";base64," . base64_encode(ourfile_get_contents($zfilename));
    }

    ?>

    … PHP code that may be familiar looking to readers of our recent PDF Image and Text Nodes Windows Files Tutorial thread of blog postings. Feel free to try the changed convert_wildcard.php PHP web application you can also try below.


    Previous relevant Image Conversions via PHP GD Primer Tutorial is shown below.

    Image Conversions via PHP GD Primer Tutorial

    Image Conversions via PHP GD Primer Tutorial

    Regular readers at this place will know about our admiration for ImageMagick and its command line (“convert” for macOS and Linux and “magick.exe” for Windows) image conversion functionality. Even so, ImageMagick is not capable of …


    convert filespec*.*g* *.jpeg

    … type of image conversion, in bulk, kind of processing (which Gimp offered with its sadly departed Bimp conversion software in the past). But tailored PHP use of the GD (image manipulation) library, helped out by (good ol’) PHP glob, is!

    And so, we’ve written a “proof of concept” converter that you can run at the RJM Programming domain, but we’d recommend for use with an Apache/PHP local web server like MAMP is! (Two in one blog posting is a record … is!)

    Get into MAMP, and you might want to download convert_wildcard.php PHP source code to MAMP’s Document Root folder. Else, try it here or below …

    If this was interesting you may be interested in this too.


    If this was interesting you may be interested in this too.


    If this was interesting you may be interested in this too.


    If this was interesting you may be interested in this too.


    If this was interesting you may be interested in this too.


    If this was interesting you may be interested in this too.


    If this was interesting you may be interested in this too.

    Posted in eLearning, Event-Driven Programming, Tutorials | Tagged , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , | Leave a comment