BrowserUk has asked for the wisdom of the Perl Monks concerning the following question:

Has anyone ever managed to create a Tk::Photo object by supplying binary data (as opposed to base64) to the -data option?

Update: To clarify, I already have the image data in memory as it is being built with GD and wish to avoid either writing it to a file or converting it to base64.

According to the the Tk::Photo docs:

Photos are created using the Photo method. Photo supports the following options:

-data => string

Specifies the contents of the image as a string. The string can contain base64 encoded data or binary data.

...


Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
Lingua non convalesco, consenesco et abolesco. -- Rule 1 has a caveat! -- Who broke the cabal?
"Science is about questioning the status quo. Questioning authority".
In the absence of evidence, opinion is indistinguishable from prejudice.

Replies are listed 'Best First'.
Re: Tk:Photo -data with binary data?
by liverpole (Monsignor) on Nov 28, 2006 at 20:04 UTC
    Hi BrowserUK,

    Yes, the trick is to construct an image using -file, and then dump the data as a string using the data() method, combined with an easy-to-use format of your choice.  (I'd recommend 'PNG' format).

    For example, in the following, I used the subroutine image_from_file() to read the image from a file, and then print the data string using $img->data(-format => 'PNG').  Finally, just cut-and-paste the data back into the program to use it as input in Photo(-data => $data) ...

    #!/usr/bin/perl -w + # Strict use strict; use warnings; + # Libraries use Tk; use Tk::Photo; use Tk::JPEG; use Tk::PNG; + # Main program -- construct GUI my $mw = new MainWindow(); $mw->bind("<Escape>" => sub { $mw->destroy() }); my $top = $mw->Frame()->pack(); + # Use this section to create the image from a file (the "easy" way) # my $lab = image_from_file($top, "./smile.png"); + # Use this section to create the image from data (the "tricky" way) my $data = image_data(); my $lab = image_from_data($top, $data); + MainLoop; + + # Subroutines sub image_from_file { my ($widget, $fname) = @_; my $img = $mw->Photo(-file => $fname); + # These two lines show what the data looks like: my $data = $img->data(-format => 'PNG'); print "The data for '$fname' is:\n$data\n"; + my $label = $top->Label(-image => $img); $label->pack(); return $label; } + + sub image_from_data { my ($widget, $data) = @_; my $img = $mw->Photo(-data => $data); my $label = $top->Label(-image => $img); $label->pack(); return $label; } + + sub image_data { return " iVBORw0KGgoAAAANSUhEUgAAAEAAAAAwCAIAAAFZLtveAAAABGdBTUEAAYagMeiWXwAAGI +lJ REFUeJxVmXmsbNlV3n97OHPNVffWHd5w3+s3tHtuB48Y2zgxtkHYaeKABR0wgeA4tgm2lR +BB RECCJE4sJRKJRASCCEVR4sSKIoFChr+iDBbYbrfd8+t+452q7r01n/mcvfNH3W6UkmqQ6o ++z 117f+r5vrQUuLjjuLi6ohkMHqZWQsmFEoSiOgvL4o6M3Pub7Mzvbqh2DgOLkKaE4GT8RQV +uB ogcIsOU7EN5mhNse9Fx8Gl2QFufo3qNBM3/xjV/OjlumYNBa1QDISHp2/p50/mEXvCZ2JC +FC 0PBChQ8+4BF6iKEQSCuSiLo4Yn73M1vtvDz4VH4ytAo0zmr0rgh6cDJ6n8ZJR08jNJ4btS +W+ gxa0QCvSk10kCGQ6bsOGtTeTZQvFarqNAKDtYOObXQ20kvufuNpHSYQgsDLFoq1sE7128h +OS 216FLxdWlpPpyWBrI17tbV39z6sigpigiSboedjiajb/VAt8pECHbbRDGDhC03SY36EpQX +go tKJfTJ/ebYKWntJRgFCSrnA1WoIAZDx6ugtIkE6Ig03/ki0/qbzw+kNM9oNi9uTAwSZb8a +zX bxKBWfhtQGjQCFpNKFbX7r8cbEhc+miEAC5GvesbnUZ19E5bP+LSR6FFhWW11ESNuVBpu8 +nx ayZgIJ1L0r2r7TAvz06SRy+rPyiQovZA4tJyJH6ziwIXQpA92NYAG7QvQgQdF649viVAoy +pp 3KasHad+7rV3d71Ql5Hr37I2MsyX0/TaEwfTrG/JtM5l4BiEq3UxOv7QyWJ4YXdMfXOhy/ +Hy +1rDb5XeMzLwxne3Wt4ZysjKALLnMB99sDzz9wZs+ZEmanSQDkLgOgLJ7Ohhaz6AxkUihO +i5 2PmllovHYPzgF+cHn2vRaAvy+jGfCxqaEXa1KfAQIHDbLsXp0PUVejDsM9wAB9GgG7GGW8 +vH JG2BRKCtKDp9Tlcj6TsqPs0WWEPU7Xs5ZGe+QBgv8vLlwiANRoNi0yc/bHoa4WKSHzFxz8 +7+ 9mr0g3Y+ePW1vyzg6M77Vkc3EQgk4IQwGw3mL/yMbAaeYHJ6PT7oL+bClr/qgmq38+njq/ +En NQ00IHDppPPPxCft5fEHh2KzP2gTImhArxm+LfSxs95mExSgAQQyBFv/en73is33ej4+Op +A9 NFtd7Pja5M5AA0Q+AB4OvfZVF9ohq8UHFscNO3lkNd22yY3VwY5Nd0KFQCNRoJAA4AhU5L +lV XYHe2rpaZEuskdD2rlV1oFlq0AReULmaUBC6hA6Oj+siShqucD1ltDUACBtIoayshUtQkl +tl kGD0Rj/U+SJfcXzweeW/lFevnk4ONjda0kphwXpahDhnEJZmUJYnYdQi72BOsLIsbj70+H ++J MyYZ2C56qgoHJVGSwO+4ru9qBj3Ojp629nI8ZnGwa2df3BQMoI3ebPZch26HsLEu8w6awV +D6 Hr5LvfpAOiI92N7/7ue1BJc1c4MSUTT08XqQHv6kLW7a2aA6uN7pgkCgW310m4tX8QQegU +tv a8Cdg2dO5h/eDOmyrQmaXaklD+6+xya7xcFOj3WKWy4OCiRC0Wj72Pp9drY33f/5ZhMcFJ +vD iMXyE+NFND/9xQg88Bwu7TI+/sJo/OnQXUNRC0DS9ImP31UnnR4oIiRIUEiBI+i0PIr5U7 +bY OucqB9VGKHy0z4ZaozSEFsh2KLshuHicH1Zqoq5PenLTxL0uCAESkLIWBq+0cqYVVVnMT4 +5f u/13epsV5XaYO02H73z3iaODvXT+bNfSL/EXsu/P4/qZxfTJNH9ycvpl3xAhA6o33nhWiK +Nk FRiwApACifR2kM5ghxbY6TN2cjOd7TYVuumj3BCs+Sfp8a4129O7gY0fWc2etMmePd6xh+ ++v R7/QdNm50EbTdxjfe8KudHL4dGutqDjqPECBoOFB22N29lh80izvP/XgwWd6HVxc/SbPdj +UP b3AxoA29AA8ip6uUWpdTPvqldLw3Ooys/RfRuoTl+vbOH+BpeiG0HYrls/HsevyGZ5c3Ry +/e uL5NpNb37OCCDx6oBi44BMrpOyxGb7enjp2rbPrJTggMEQgHFwdBwJoqFQI0gQ+RZEORnv +1o PO8Xy2a2CM/2m/XsB49eeddi/zf2NmmHdCOy+d+49/KezR4pbw9mD3ZHb3ymo+m1mgiNRO +B5 IITC1ho8VIyEsuGqRlkfWx8KepFXLfO7t7/S7b+a5N9W7txrkE/GntTIgDpC7i3iR24+/N +sn KV5DJkt1YXv36OguYCQYT+GA0YqGg3R1VZ3nJ0KGIszdFrUBDR4IMEOkwLYFiQbLEKFwa+ +gq 11rRw/hBI7RF6mkqyY89+0MCuX6WElhJpR23Nk5VG1elg41gdGwEQ8kKJgIEqAayQINQRE +1m MWWJKdCKxNLoES8hR9GuxByJAA+RI8GCdXzH1XVu6kqDCJgmzy6mB6IS2lhhHWVwvH3A2s +AI oyNBWYBDFR1Nrj/9F/7gbEGv9/bx4nuUUrq5KRyhcSpRrlGCQWM2Ql58/jd8/5vz7LmtPU +2Z 5kmuLFgljKe0xFkYs1HjOH5O2TDHC9nM0JfRb29v/k5S+ZXIED3qiWdaQoORGDekzLo9Uy +cc 3v1pX75AcVtFiRGyKK7kq7cJveu10jw/bTVvnIzLh/b+WdgiLXj5hZ/oRVO/dScdHQX9y1 +n+ 2M6Vfz9NwQTY1DMenZYQyCDoOi6hR7r469nscjnD2st28kPL13/tckgTWiJS4PtojdCAJ1 +QH hdC4miz+6vg2dtG25q9d6L0JCoXPmgW9rgebIfn880dvbFfTpllcmxz/SlvQBB8ZEiiCIJ +TK J2opBK6LEIg15BT9Pqf3Pmftbn4UTe4/+6Yaez6A0IrGQHGtz/Gr12YPhE2un9z6CC697l +BI VAPdxnPxYKfxUIBz9+4/Tu0nRoc/24I2ewJQRB7FfMtmV1Z3fszDQwM9HyRUhiS3PP/iTw +8v 2cC9XJuPXnj4v1KSTauWZXL/Y6vDj7YNm25nuToedMq2m6eL55QeWUgxClRNKSjrD5q4lE +Gs aFBLxCQXSGEBacDK/PTgvtu7Mdj87dwifVFQWwf8Fyt5WGvGxSwR8Shm/6RMl+9utT6QCw +rO KjACa7F1pxZYlUINEokVaNAWz9rKWGdw4WK1lKYCoU0hPN/Pc3Z69+F+llNLjVMR8cT3/W +bH I0m+VgqQMQZrUTVC5IgSMOSICgtrKwHGCqyQi/lxnBeuGhJKVJnWx0ri50Od79ZWE1Qo6s +L1 xG6y0sIgjYcFiSCQBikXkhorIUeAlSCl44FIa4sxTlEl7a32Ih2RFZR6zQeVHllx4FGRQK +6J BcVB269CTaTybgNtcFGOZTp5TXVaSrfA8KaiSYNBYhSdzhVXY+J914WayL2kDYvFr9zbf8 +9k /vFWSN/Br6uWzJsRr77y6P7xw6/ce2+REypHkGGJmjHIumhaHARYJTGyKrQOAIj7TbdTxS +fK xXNVoe9Yl3v3vlOkD4rsT8bzq/cffLjl0Yy4/fqwc3klq/3htlUOcYVyq06LVXrXzs+02r +AE 2LVhNEALje9xvUl5sGmnN5azH3XQaBT0HU5vvdPOmsmRa5fX0snNfPl4Me7a4v2Llz90sY +Or QeJHckNiskZ+0tryzlsl8PTalYLW0JbY4mPZtGHjH7jWAQ902xGd0GFy+sOjw2Y527L5jT +Ld ruvgZP/aQDEMtaNBIx1W9z6dLTfmo8cGPj6Stc1x1tKMo4kimI0/bc2VYrxtz37cbdB06T +cG a17p+7QFPdhyaQk2GjS1F7htJFGPK5exZx+0xd4br19tKbx1DtSaMBQgFb0Q9jaYn77bJN +vV fNuu3nl1gy747AoCFK1tH40jgCFs++3LMBT0PMVq8iU7uZBPu8v5M12Noo+7Pnqw/kLR8o +gG HvdvfXZ+8o50MqzuNfKDa+nxM/2AdkCz1Y82e3jgggxotGkTdRohbIbY/JIt28nJcNhF4c +EG GqXw6J3fkQCFDqCt6AZM9384uz208yfnD1rx7KH5yc+1NbttFRBoJHQcNxQeYchWSH3wXn +s2 sPby7MGH286aSBsgXUGIg8ADvTaqDS9qiuihLb03YPzK57PFY2cjYe12Mo1s9nY7+5H5/q +e6 Hu2AS9tMR18wyV9d7F+2k8v2aK+af+RCa+1VHaQENI4HQiAtDjJHQoVgQ5EM+vF0jhaMx5 +9Z JP9pa6e7PNxvbl4h8a1Tl+aBLazLIEtN0C0hrsSVTvdPGz4VwWRWW1EIkDYSxEIIrI0gx6 +kw UA8EcdhM4wwqIoFn+bNv/dSlvVPdOKWemWpBmYkc0d4hCdPi6tVrX1+mxNDthrOJleRrqj +Bg bUfhnOcZqwWBwlM4Eimp1fm8AsfVxoBw/bBflQKE49dmbf8lYaNZliAVusYBh3XTge0gHZ +wC jbBIgRa4EkfhCLRFQtQkN+BAALWjor4tk3V1+o1+VdYI7YSRqUqlrTRocJQ01iLBobcbiv +NW lnVvCOL8h0BYa/vdwWQ600iDBdlvd2bzUbspF7ERAkBahGHQYTY7j1YKhGUtYkJxa/9npR +5T tzGBsAoMMkVmUdc7evD6YDCIk9pzd6cn6uMf+9179yjBgOOzKqgFQYPVHOx6wAa2AVLJXH +vW GMqiEJrIYmpKRMX5jGidEOl4UZnEgYMpzYUtd3xc9Nskc5TixVu/1h4eZvVzy+Tl4XAwm9 +6P glBaLYySVmMlVmEcrKSqESUyRhiLb62H9axA9aL0+EEQNE8PD1tB4O5dWLz8SuuhbdJWaS +5m 8aWr136/sBioi40UD87QBSbC5sgcELWUeMJFG0yNsWtnK88LG+1Q5cLiKxyLKzlZ/qPl8Z +96 3r0su9u6MCCdQ1mVtfZbdS6s8a11QWElwhhRg5FWycpFWCPjWjimHtS2Y2xgRaHVLC/O2m +Gr TMpANct44nRL0jGeW6bG8bcRzbNl3em/t939h5mhdqGGugUKMcWgraPxxRpAUlEaYa1GSD +Be JBxVKEGZcevVL3fbI2nvpvHr7UYthEGp04PxYGsL1cwSR6kLSdK5cf1rpsbRJDlGYRTao6 +pp eCQxBrQDFXFKt31xMj/QnrEWoYgCqoxBn1uv//zR/jcGjZm3GbI8pVZlFdT2YcRf7O/8cs +Jb 0AABNa5BInWlaEQiXljQAi1tpShJcCNeeukf9Lqjuv5OFr/S2bDx8rgyclWEjeimcZ549G +3/ 4/ToWEJuXwJhaJY4VekoPAtZuSCLEWUcgwKLllQZG1sXT45PkUGdF4g6chvzZVJXVVgNws +7v UbN/+2e87FXcVZ2cOZ7n5LOseCkEU5GJt+jhrWiMOMeLiEQtFfWgJZJVLAX3j76k9evY20 +6U 2myWp5nfHZaLnXHynmvX/6mtwCJwBt3eeDra2GQZk+Q0QqSgyCkqaotZs4NFChpN8gILwu +K7 FDG1wSJr8CKRpHWj469mWc+n2eD5736/Vs9FLZWNll40tOL9vf5/SC2FAqDugHRZSkqNVN +RW OW5VFw3HmS/m3QbPP/8FV7yg5D5qauJMyLbrPjQ/3Hz6nX/0YPG/KksYbSWrlSvTk2T0yo +Ov RO1j1z87Hc0Dff3tD3+1zPBxIufCvMwC5aT1fSE5Ovyts/jfRc1jYVxZPX5l8Ce+kstyp8 +Sr 4lHDz+NZFkXklnhO0HpMUybje4EbCbdlY6kskhZmgQJyUIYa0KqqDZTF1MKi9HzFssJtHh +l7 xxSnTtjL8o4KHt+8+LW8oLe5UVUnWPJV6aO7us5Lthsvr+L/03StE4TFaiATHKgoV+WDdh +hM k6UUKEudhJvNp85mzwvparlZQlKaitSSQ5JmRkG2pJYol17/Xx0/+FvCVZVzoNQ4U0drQV +K2 UVc5MkVQARa95hyLsGgIrM2NpcbBKMfRWDM+Ld/3vq/ZksKwLGt8hHTrlTWYs4JGi/uny9 +1L V1b10vpbD+6HRcCiRCg36siTYllpEAjJjae/mKwQhrqitt+sBZWiNmcgsfLPJciiaqRCUA +oq RC3+HPI55Ij6vJQta+ci16wP2qDs+V+O8vy6tsLEW9tPZ/HrRQ2Ou5ou8Bs2y1BLa2xpwX +pP Xv+6BCEwlgLq9RjWs7NVJrouVYHBGo4OURZfUhuUpDaYc8Y2bx0dqwVCmVIqhIilSCXFem +Zm wZAbynOlsuefmnUqpMBYC4h1ABJllC5LW2VlIiS2jmwdoyFfncuFouGRpvm6rrQNcoyiFM +rI gKIwaOyywICKyD2JdZgpYxX4DjanhtpQy3OVlVYLfIlUplQCJReYGFGDNtYBWJ9+Lcno8w +zU AuVQVxZZOrosa7Tl7CTZ2amclnZkUCYrFKKMkQhHuXYrT5aKRRSgYf/oK1V1P/DM6cn84o +Un 792tnnjyV8uEALKCTmdrGs87DTIxCV2U5datz0sVN9uNs2nV6d04OOLhR79oKjxFbozCQu +1r 3rj9Oa/5UjpdTSaTjctvq6bBmsysMG96CrF+a8d1y7JAIB2Ug7aQosxGnli/oahqaRcv3/ +rJ R5/4t5MlVVLntgApJZ0e8ylSvdQOD1WYXOzm+7f+eLh1/XT0ifFJ+13v+MN0hZ0dP9RnMu +V4 /7NR+FqV3TLmXweBi5Bht0i5FLafGmxwckBmdLcVzRbzhvTrkkZjgZoEfpEn0sYK0wcsHq +Tn lgspqCWVLksfq2RgsVmWoQ0PDSDddExvuX+3ObzYaLmn9/77/uHf7DR/p7ZYdYJEBpzNkQ +bN zujgwc5FhRhfuKaS028q51u7V4YvvbrTal7P0uYqDjpddXb69fZOS49PZ9Mk7LyNXDrSOz +3z 2r2r41MqQW3FOJsjyEy202eV3Gv5h3kx71y6Fh8g6VjWHVKK5bzoOR8pdlDWCVSZTJBoQ1 +dC xf2Dv+KHr2HSVXza2GouJ7vXLn5jVZI46FarOgNkS1tp51JwNvl7xn6rKF93nEJSiUa3nM +4R lVWyEjYIvDyZigrPG+anvrA3XP+R7Qu/VSviGuuSFiDBcSjKVs3B3d9sXP6fZ0f/reE5Xu +/G 4Svq/T/w3ZNTclo5CbLCagBbvbV6Wk8yHYFWFJpSKdo9vvFnH7x4eWHLe/UKXQ8Rj1za+Y +9j TdhnMaFOpLB9V3lFfdZppUUNsLPLC9/5qcXZka+VMr61YhGvoq4Xdsz49KjT2UqTrSsX/t +AR xClK9SqbCrfObSE96hgl6Cvuv/ERrz9erO4HUc+a3TS+fuXi79YFFRREFSBj1Jv2H31OUV +gt CNeDc0Xe6/H89/5uaf93GBx4KnYbzcX+qtW7RvP65NS5evH3bEGnyemcKArncdFt7Z4t5h +IM pavrqspA95v9+XIm0YHbWRSpp6O4SobD7cPRPiCFNTZTqqptLRVRiMk5euXjzc7hfHarvd +mY JUmn/6Fe8PUqo8QxeLVY1fJNGrWs/dtbASCIJJ5CSFahk1eG557/3NWbxXL+rTBcpNlp5G +kR dpjMCfvzUdiOPrS399VljEEY5aYmtx5VjQiwOQRoTbWEGirvwpUn9u8cIErCmjzGusiIUn +R8 U2SjMOKFV3/BES/0wlG1vKMjRWNruerdf3Dh+9/1x2mua4Y1BepkbQ1FjTSOIHgTQnYdgA +Yl cQRWkSqM62AFyuH1N34cOe6GCcScjWgOcBxMluW139w5OHJ73Q8Nh3+/qqhBaJmXJmg00m +Sl HaoKDMgQY5E52gDaxaZ4hkjz0ve+1G7f0c63BQ8QBu2aXArn0dny3Xt7/7I05MY3hADEyF +xI lEEZKWgI8M7vH/PmXA1hz33rZq87mUzbbawhLbj92per5IXNmx3icTK/p73E7en52aF2A1 +M3 Q+9yXW67raeGwa/biq1N9o9xfZYZBnwfBGkOmmaDvOD+3c9KM271YHG4Gt1vPHyF0R28Mi +9c z39iGd+4fOGfW8WyxA1baZqCxAK1olJvdvJC4IC050OJ8s2mDGqkVYqmK4LSLj1ZSF2UJb +7C j/j2936p5lXPH2s1bfeC2cm9Ts89PZ4MdrfJcmxjOp52h0Pq9slpZ2Pr2v7BK91eKDHT6X +Tn wpWzwyMpizA0Xt+Nj16M2uFifNy6cL2c1k7vifFx++Erv19VlGChsDIImkm2fMtxCNuQWE +UM CCHAYnFY24r1WkLgeJQx2JYr26XJXMqNLe9oNFrvUmWNJzA1rRb/9xs/t3czqFd3jZkV2T +Tq +OVqijFVoaQjK1ZWLKNGLSjXbqdcIgh1tJXPU+35aBcVJIVZLCo3eGTv2r9ptzk5wlq6ne +bZ bClwLfb/8xFrK4Fhvc/CYs1bG6UcVa6TIBQ2b643OFk5bTbNMlmnSGOqqBFms1ojWyos6r +NA on2swgh8n1duPZYWI9c10hpprMKRno/RpBm1QWhUgDMw+eDS3h9ph8UCCwWh8PtxNkWtsH +iq U5ZGrE3oWy+BkeszR9D4fy8h5JwCOPDUAAAAAElFTkSuQmCC"; }

    s''(q.S:$/9=(T1';s;(..)(..);$..=substr+crypt($1,$2),2,3;eg;print$..$/

      Sorry, I guess I wasn't very clear. I already have the image in memory in binary format (from GD), and I want to avoid converting it to base64 or writng it out to a file.


      Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
      Lingua non convalesco, consenesco et abolesco. -- Rule 1 has a caveat! -- Who broke the cabal?
      "Science is about questioning the status quo. Questioning authority".
      In the absence of evidence, opinion is indistinguishable from prejudice.
Re: Tk:Photo -data with binary data?
by hossman (Prior) on Nov 29, 2006 at 02:23 UTC

    It looks like your (and my, and everyone else who has commented so far's) expectation of what "the image as a string" and "binary data" means doesn't jive with what it acctually means. Try this out and it works okay...

    #!/usr/bin/perl use strict; use warnings; use Tk; use Tk::Photo; use Tk::PNG; my $file = shift or die "put a PNG file name on the command line"; my $mw = new MainWindow(); my $src = $mw->Photo(-format => 'png', -file => $file); my $tgt = $mw->Photo(-format => 'png', -data => $src->data(-format => +'png')); $mw->Label(-image => $tgt )->pack; MainLoop;

    Inspecting the output of src->data(-format => 'png') to understand what exactly the differnce is is left as an excercise for the reader.

      Turns out it's a Base64-encoded version of the original .png. I say version because it's has been transformed, but it's still a .png, no more no less.
Re: Tk:Photo -data with binary data?
by hossman (Prior) on Nov 29, 2006 at 02:15 UTC

    I don'treally know anything about Tk, but the problem intrigued me ... one thing i noticed is that when i went looking for info about Tk_CreatePhotoImageFormat mentioned as the method for registering image format handlers, I found this man page which indicates that the image format handlers are expected to provide seperate sets of functions for dealing with string data vs file data...

    • fileMatchProc
    • stringMatchProc
    • fileReadProc
    • stringReadProc
    • fileWriteProc
    • stringWriteProc

    ...presumably this is so the handler can use an optimised method for getting the data out of the string or file if it knows a shortcut, but it seems silly to me. Either way: it leads me to suspect that maybe the image format handlers in Perl/Tk only support base64 encoded data in their stringMatchProc ... who knows what the stringReadProc does.

      Thanks. The answer appears to be one of:

      • I'm misreading the docs and it isn't meant to signify that binary data can be read from a string;
      • The Perl docs are basically just ports of the underlying tcl/tk docs, and this particular feature has never been implemented in the perl/tk wrappers.

      It'd be nice to know which it is, but either way, I'll have to look into a Win32::GUI solution to achieve my needs. :(


      Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
      Lingua non convalesco, consenesco et abolesco. -- Rule 1 has a caveat! -- Who broke the cabal?
      "Science is about questioning the status quo. Questioning authority".
      In the absence of evidence, opinion is indistinguishable from prejudice.
        I'll have to look into a Win32::GUI solution to achieve my needs. :(

        Hey! You are breaking the tendency!
        Usually speaking of perl/Tk people tend to say "but Gtk2 is even better", not Win32::GUI!
        :)

Re: Tk:Photo -data with binary data?
by calin (Deacon) on Nov 29, 2006 at 00:55 UTC

    Consider the following tcl/tk program which works correctly:

    #!/usr/bin/wish set fdata [read [open "test.gif"]] label .l1 -image [image create photo -format gif -data $fdata] pack .l1

    A similar Perl/Tk program dies on the same .gif with various errors. I got:

    no image data for this index at /usr/lib/perl5/Tk/Image.pm line 21, <G +IF> line 1.

    and

    Segmentation fault

    I have the Debian (etch) system shipped perl (5.8.8). Tk is 804.027, also system.

    Update: tcl/tk is 8.4.12

      I have the feeling that this post is telling me something profoundly significant, but I'm not sure what it is?

      Are you saying that it's the perl/tk wrappers that are broken not the underlying tcl/tk code?


      Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
      Lingua non convalesco, consenesco et abolesco. -- Rule 1 has a caveat! -- Who broke the cabal?
      "Science is about questioning the status quo. Questioning authority".
      In the absence of evidence, opinion is indistinguishable from prejudice.
        perl/Tk do not have underlying Tcl/Tk code, because it is a full migration of tcl/Tk to Perl, with some possible mistakes in the middle.

        So it is quite possible for some feature to being improved in Tcl/Tk but is stale in Perl/Tk.

        I beleive you'll got that snippet of your code working via Tcl::Tk, which provides Tcl/Tk with perl/Tk syntax; but this module do not maintain 100% compatibility of perl/Tk syntax, however.
        But you'll have a possibility to use those Tcl/Tk libraries lacking in perl/tk

Re: Tk:Photo -data with binary data?
by renodino (Curate) on Nov 28, 2006 at 20:59 UTC
    Not certain if you really mean binary data, my understanding is Tk::Photo wants Base64 data, so you just need to run your binary image data thru MIME::Base64::encode_base64() and supply that output to Tk::Photo(-data).

    Or use the handy bintoscalar utility...

      I actually do mean binary data, per the Tk::Photo docs:

      -data => string

      Specifies the contents of the image as a string. The string can contain base64 encoded data or binary data.

      I have the image data in memory, and wish to avoid either writing it to a file or converting it to base64.


      Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
      Lingua non convalesco, consenesco et abolesco. -- Rule 1 has a caveat! -- Who broke the cabal?
      "Science is about questioning the status quo. Questioning authority".
      In the absence of evidence, opinion is indistinguishable from prejudice.
        Well, it will very much depend on the image format of the data (eg. "gif", or "jpg", or "png", or whatever).  Tk only supports certain image formats:
        IMAGE FORMATS The photo image code is structured to allow handlers for additiona +l image file formats to be added easily. The photo image code mainta +ins a list of these handlers. Handlers are added to the list by register +ing them with a call to Tk_CreatePhotoImageFormat. The standard Tk distribution comes with handlers for XBM, XPM, BMP, JPEG, PNG and PPM/PGM formats, which are automatically registered on initializat +ion.

        and in the next paragraph ...

        Usually this will find the correct handler, but if it doesn't, the user may give a format name with the -format option to specify which handler to use.

        I'm assuming you know what the image format is of the image you have in memory.  Why not just try displaying the image yourself?  As the Tk documentation illustrates, you can use:

        my $img = $mw->Photo(-data => $data);

        and if necessary supply -format => FORMAT (for one of the valid IMAGE FORMATS above).

        Have you tried doing that yet?


        s''(q.S:$/9=(T1';s;(..)(..);$..=substr+crypt($1,$2),2,3;eg;print$..$/

        Dunno, the following example should work but it doesn't. It seems that some formats can't read data from strings, for whatever reasons. This is somewhat hinted in the docs:

        data => string
        Specifies the contents of the image as a string. The string can contain base64 encoded data or binary data. The format of the string must be one of those for which there is an image file format handler that will accept string data. If both the -data and -file options are specified, the -file option takes precedence.
        #!/usr/bin/perl use strict; use warnings; use Tk; use Tk::Photo; use Tk::PNG; my $fdata = pack 'H*', join '', map {chomp;$_} <DATA>; my $mw = new MainWindow(); $mw->Label(-image => $mw->Photo(-format => 'png', -data => $fdata))->p +ack; MainLoop; __DATA__ 89504e470d0a1a0a0000000d49484452000000100000001008060000001ff3ff610000 000473424954080808087c0864880000031149444154388d5d934b685c6518869fff9c b9672699c4244c27186348a6dad462e9c6120af5428ba274a1502b144a45501071ab2e 155d195ce842d4950bc18d2e24daaad5452b4a3596c4b69a26c44e636e93c964a69999 73ce7ff95cc496c667f52ebef785efa6b88391936799fbf408c327bece88b5bb9c369d 36d4b848d79cb1ab2b3f9e6cf33fd42d513a7d0e7192146bc7ad754f86b1cc01a36205 17196836ca5e6d63c606c1e71877b1fafb8b764740e9f97388901291d75c22737a78cf 60f1c8de9cb7a7dfc747b8bcacf961aa2217cffc36afab1befdb407fd4987db505a046 4f7d87f2bdac08efe4ef2ebe7cfcd17b38ba3b45dc87283224123ea0700267671a7cfc e179ca53b36f99adf69bade5d7230f4f7962dd31c9e64f1c7b7898bdc524cb5bc2b595 90563324080c4b75433d84fb073b79eed438b942ef0bce98c7003cb1aea0bdf8332363 433ddd1d71166ac2f5d536439d96fd436976f7f9ec2f28c6fa84f99a90e9e9a274f460 9f75f26cace38d6c4c8cbd5765b3877abbd3aa5cb30c77043c7e5f9c819ec4ed49a712 a0adb0d1b44c2e785ca3df733dfd07a4fcf788e7b4c978e9f45d952881d2214fef4b52 ec8edf368b0800314ff144c92712a89804b650ec126db231ab0d8186b94d8525cdf4ba e250069a214caf81b68e870a8e6432cee5aaa2d252dbcbf36288133cd1c64537db6669 d3706151f1cd3c680b5b11fcba04d34b42181aacc057b370bd0668039bb508d09ed366 9dc6e6acde0a080221d2020802e0605bfcd78e0565049a81b078e306b016b391998bad 2e4ee672bda3aab42fbe50b55c287b8416ca0d505631b5e2c106fc59817cdcd29cfa29 8aaa956f81b202e83bf8c998f8c9cf3ac60f3f901e18209f024f413ddc3ed57c0a222b d4db42fdd28c54bef8f2175b6f1c8789b20f90293eb56e5bed69b3f4cf239938d9743e e7c51331b20945260e38836bb5d83cffb3ae9cf9fe0f536fbc84bc7b75c7337595dec3 19fb20c82bf9c181c35d83c5a154ae433963a455addb8db97279edd2d549e003e02f98 901d01b7c8ec7abbc7467ad4467accf7fda26907ce867a71dbc41598b87967fdbffa74 99fc896501e90000000049454e44ae426082

        It dies with the error:

        couldn't recognize image data at /usr/lib/perl5/Tk/Image.pm line 21, < +DATA> line 25.

        If I dump $fdata to a file and then use -file => ..., it works.

Re: Tk:Photo -data with binary data?
by zentara (Cardinal) on Nov 29, 2006 at 13:07 UTC
    Hi, when I first encountered this, I was told( by a Perl/Tk expert) that the Photo object wants base64_encoded data, and the -file=> option, does convert the binary data to base64 internally as it is read from the disk. So I don't think there is anyway around it.

    However, if you are willing to switch to Perl/Gtk2, you can load binary data. There may still be a bit of a slowdown though, because the Gtk2 pixbuf wants all images to be 8-bit 'rgb' (+ optional alpha), so the pixbuf loader converts all images to 24bit or 32 bit data. Here is a simple example:

    #!/usr/bin/perl use strict; use warnings; use Gtk2 '-init'; use GD; use GD::Text::Align; my $time= localtime; my $image = new GD::Image(200,30); my $black = $image->colorAllocate(0,0,0); my $white = $image->colorAllocate(255,255,255); my $text = new GD::Text::Align( $image, font => gdLargeFont, # font => './arial.ttf', text => $time, color => $white, valign => "center", halign => "center", ); # the order of these two lines is important $image->filledRectangle( 15, 15, 150, 150, $black ); $text->draw(100,15); my $gdimage; open( IMAGE, ">",\$gdimage) || die "$!\n"; binmode( IMAGE ); print IMAGE $image->png(); close IMAGE; #gtk2 stuff my $mw = Gtk2::Window->new; my $vp = Gtk2::Viewport->new(undef, undef); $mw->add($vp); &load_image; $mw->signal_connect('destroy', sub { Gtk2->main_quit }); Gtk2->main; ########################################################### sub load_image { my $loader = Gtk2::Gdk::PixbufLoader->new; $loader->write ($gdimage); $loader->close; my $pixbuf = $loader->get_pixbuf; my $image = Gtk2::Image->new_from_pixbuf ($pixbuf); # my $pb = $image->get_pixbuf; # my ($x, $y) = ($pb->get_width, $pb->get_height); # $mw->set_title("dim ${x}x${y}"); $vp->add($image); $mw->show_all(); }

    I'm not really a human, but I play one on earth. Cogito ergo sum a bum
      I was told( by a Perl/Tk expert) that the Photo object wants base64_encoded data, and the -file=> option, does convert the binary data to base64 internally as it is read from the disk. So I don't think there is anyway around it.

      Thanks. That knocks the final nail in my pursuit of a faster method using Tk.

      It seems weird to convert the binary data to base 64 though. It must at some point convert it back to binary to manipulate it and set it into the underlying hardware buffer/device context. Passing it through an ascii-based intermediate format is just pure overhead--though that does explain the rather tawdry performance of Tk image manipulations.


      Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
      Lingua non convalesco, consenesco et abolesco. -- Rule 1 has a caveat! -- Who broke the cabal?
      "Science is about questioning the status quo. Questioning authority".
      In the absence of evidence, opinion is indistinguishable from prejudice.
        I asked about this once on comp.lang.perl.tk and Steven Lidie replied

        "The reason is described in various pieces of documentation. Tcl/Tk required (still requires?) data in "printable characters", hence the encoding of binary data.".

        I never thought about it, and just took it as one of those truths you just accept and never question. :-)


        I'm not really a human, but I play one on earth. Cogito ergo sum a bum
Re: Tk:Photo -data with binary data?
by eserte (Deacon) on Dec 13, 2006 at 09:14 UTC
    Tk805 will probably support binary data for the -data option.

      That's really good to know. Thanks.

      I would have raised this as bug report but it was never clear whether the 'bug' was just my misinterpretation of the docs--plenty of other people assumed that 'binary data' meant base64 encoded binary data--, a deliberate omission, or a limitation of the underlying Tk libraries.

      If you have any influence with those that will implement this?

      What would be *really nice*, would be the possibility to (alternatively) pass the address of a buffer from which Tk would update the underlying windows bits when instructed.

      In an ideal world, it would be possible to use a graphics (painting) tool, (like GD) to create and/or modify images and a presentation tool (like Tk) to display them; with having to go through multiple copy operations and format conversions to pass data between them.

      Presumably, all Tk::Photo does with the data passed is convert it into the format required by the underlying OS window primitives (eg. Bitmap for windows), and then pass the converted data on to the OS for display. Tk::Photo makes use of several packages (Tk::Png, Tk::Jpeg etc.) to do the conversion.

      GD uses an internal format of it's own making (the GD(1) format). I'm wondering about the possibility of adding a Tk::GD package to the suite?

      If (a to be written) Tk::GD package could accept an address, and the authors of GD/bgd could be pursuaded to expose the address of their internal buffers, then once the connection was made, you could use GD to modify the image and simple force an update to the Tk::Photo widget to have it read the bits directly out of the GD buffer. That would save several copy and convert steps along the way.

      The current situation of either:

        1. Draw with GD (in it's gd format).
        2. Export (copy and convert) the data into (say) Png format.
        3. Convert that to base64.
        4. Pass that to the Tk::Photo widget, which converts it back from base64 to Png.
        5. Passes that to Tk::Png, which converts it to whatever format the underlying windowing system requries.(eg. BITMAP on windows).
        6. Then throws those bits into the device context in the OS windowing system

      • Using a Tk::Canvas object with all it's hit testing, scaling and other potential, which is great if you need those facilities, but horribly slow for your basic pixel painting applications (eg. Tk Mandelbrot Fractal).

      makes using Tk for graphical applications (rather than window/dialog building purposes for which it is really quite nice), a PITA.


      Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
      Lingua non convalesco, consenesco et abolesco. -- Rule 1 has a caveat! -- Who broke the cabal?
      "Science is about questioning the status quo. Questioning authority".
      In the absence of evidence, opinion is indistinguishable from prejudice.
        Tcl/Tk lifted the restriction to only base64-encoded data for gif images recently. This means it is just a question of porting the Tcl/Tk changes to the Perl/Tk source code (I am currently maintaining a set of patches against Tk-804.027, so this could maybe also go into the patchset).

        As for the Tk::GD thing, I think this should be possible. Tk has various image types (Bitmap, Pixmap, Photo). And for Photo, there are various handlers for different image formats (gif, jpeg, png ...). It seems that Tk::GD should be implemented as another image type. You can look at tixGeneric/tixImgXpm.c or generic/tkImgPhoto.c in the Perl/Tk sources to see how to do this.