A faster way for changing images?

Visuals, audio, animation. Blended, not stirred. If LiveCode is part of your rich media production toolbox, this is the forum for you.

Moderators: FourthWorld, heatherlaine, Klaus, kevinmiller, robinmiller

hairydalek
Posts: 57
Joined: Sat Feb 01, 2014 8:57 pm

Re: A faster way for changing images?

Post by hairydalek » Thu Mar 03, 2016 10:39 am

Currently looking at ImageMagick (discovered this yesterday) for this. It’s quicker, but not sure how I can bundle it with the app yet. On a Mac it seems to require X11 and XCode tools to be present, which immediately makes it non user-friendly to install unless you like the command line.

sanke
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 10
Joined: Tue Apr 11, 2006 7:31 pm
Location: Germany
Contact:

Re: A faster way for changing images?

Post by sanke » Thu Apr 14, 2016 7:54 pm

Hi hairydalek,

I looked over your convolve-blur code and have tried to speed up the script. My attached code here is about 5 times faster than your script, measured by processing an 640x480 image on Windows 7. Using LC 4.6.1 ( + the Metacard-IDE) this takes about 10 seconds for your and 2 seconds for my script. With LC 8 DP 15 processing time is 24 seconds for your and 6 seconds for my script.
I added both scripts , and a third one especially for LC 8 DP 15 to my stack "Image Toolkit Experimental". Because I am new to the Forums I am presently not allowed to include link references in my posts. Heather mentioned a workaround with substituting the dots in links by the word "dot" between spaces which you must then delete.

As I just see, this workaround does unfortunately not yet work here. Maybe I can send you the address by mail? See my mail address one the use-list.

Your script (with "chars") would not run in LC 8 because LC 8 does not tolerate "char" and "numtochar" which need to be substituted by "byte" and "numtobyte". Strange as it is, however, convolve scripts need "chartonum" instead of "bytetonum". I have also integrated the "progress bar stuff" into all three versions - which causes almost no difference for the processing speed.

The "Image Toolkit Experimental" is a slightly altered version of my older "Imagedata Toolkit 3 Preview" from 2006. It contains different versions of general convolve filters 3x3 and 5x5 along with about 200 other filters of which about the half are encrypted, which means you can use my stack with all Commercial and Indy licenses, but not with Community licenses since LC 6.0.
Chris Bodell - with his "PhotoRoom" - has "borrowed" his basic convolve function and quite a number of filters from my "Imagedata Toolkit" of 2006, a fact he acknowledged in this post:
"Re: Image Manipulation
Postby cbodell » Sat Nov 12, 2011 5:32 pm
I have seen the imageData toolkits, most of the basic filters are also included in my engine. .."

One of the restrictions for a newcomer is also a limited text space, so I will continue to add more information in future posts to this forum.

Kind regards,
Wilhelm Sanke

Code: Select all

on mouseUp # new convolve 
  set the cursor to watch
  put the milliseconds into Start
  set the cursor to watch
  
  put the milliseconds into Start
  put the imagedata of image "x" into timagedata
  
  put buildArray(long id of img "x") into tData
  set the imagedata of img "x" to tData
  put the milliseconds - Start  into field "test"
end mouseUp


function buildArray tDataSource
  
  put "1,1,1,1,1,1,1,1,1" into Convarray
  put 0 into tW
  put 9 into tscale
  put imagedata of tDataSource into tData
  put the length of tData into tDataLength
  put the width of tDataSource into theWidth
  put the height of tDataSource into theight
  put theWidth * 4 into re
  put 0 into tIndexCounter
  #==========================================================

  put 0 + item 1 of convArray into tA1
  put 0 + item 2 of convArray into tA2
  put 0 + item 3 of convArray into tA3
  put 0 + item 4 of convArray into tA4
  put 0 + item 5 of convArray into tA5
  put 0 + item 6 of convArray into tA6
  put 0 + item 7 of convArray into tA7
  put 0 + item 8 of convArray into tA8
  put 0 + item 9 of convArray into tA9
  #=========================================================
  
  repeat with i = 1 to (tDataLength - re) step re
    add 1 to tIndexCounter
    put byte i to (i+ re-1) of tData into tDataArray [tIndexCounter]
  end repeat
  
  put numtobyte(255) into tAlphaBit
  
  put "" into tData
  
  repeat with n = 0 to theight  - 1
    put tDataArray[n] into treData2
    put tDataArray[n+1] into treData3
    put tDataArray[n+2] into treData4
    
    repeat with p = 2 to re -4 step 4
      
      put \\
          numtobyte(max(0,min((chartonum(byte (p-4) of treData2)  * tA1 +\
          chartonum(byte p of treData2) * tA2+\
          chartonum(byte (p+4) of treData2) * tA3+\
          chartonum(byte (p-4) of treData3) * tA4+\
          chartonum(byte p of treData3) * tA5+\
          chartonum(byte (p+4) of treData3) * tA6+\
          chartonum(byte p-4 of treData4) * tA7 +\
          chartonum(byte p of treData4) * tA8 +\
          chartonum(byte p+4 of treData4) * tA9) \
          / tScale+tw,255))) into Tred
      
      put \\
          numtobyte(max(0,min((chartonum(byte (p-3) of treData2)  * tA1 +\
          chartonum(byte p+1 of treData2) * tA2+\
          chartonum(byte (p+5) of treData2) * tA3+\
          chartonum(byte (p-3) of treData3) * tA4+\
          chartonum(byte p+1 of treData3) * tA5+\
          chartonum(byte (p+5) of treData3) * tA6+\
          chartonum(byte p-3 of treData4) * tA7 +\
          chartonum(byte p+1 of treData4) * tA8 +\
          chartonum(byte p+5 of treData4) * tA9) \
          / tScale+tw,255))) into TGreen
      
      put \\
          numtobyte(max(0,min((chartonum(byte (p-2) of treData2)  * tA1 +\
          chartonum(byte p+2 of treData2) * tA2+\
          chartonum(byte (p+6) of treData2) * tA3+\
          chartonum(byte (p-2) of treData3) * tA4+\
          chartonum(byte p+2 of treData3) * tA5+\
          chartonum(byte (p+6) of treData3) * tA6+\
          chartonum(byte p-2 of treData4) * tA7 +\
          chartonum(byte p+2 of treData4) * tA8 +\
          chartonum(byte p+6 of treData4) * tA9) \
          / tScale+tw,255))) into TBlue
      #=======================================
      put tAlphaBit & tRed & tgreen & tblue after tData
      
      #======================================
    end repeat
  end repeat
  
  put  tDataArray[theight-1] after tData
  
  return tData
  
end buildArray
[/code]

sanke
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 10
Joined: Tue Apr 11, 2006 7:31 pm
Location: Germany
Contact:

Re: A faster way for changing images?

Post by sanke » Thu Apr 14, 2016 8:06 pm

Hi hairydalek,

I just provided you with the download address of my stack "ImageToolkitExperimental" by using your forum mail account.

Best regards,

Wilhelm Sanke

sanke
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 10
Joined: Tue Apr 11, 2006 7:31 pm
Location: Germany
Contact:

Re: A faster way for changing images?

Post by sanke » Thu Apr 14, 2016 8:30 pm

For those who are interested to download my "ImagedataToolkitExperimental" immediately:

View my alternative website address in my User Control Panel and add (behind a slash) the above stack name (no spaces) with an added ".rev"

Wilhelm Sanke

[-hh]
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 2262
Joined: Thu Feb 28, 2013 11:52 pm
Location: Göttingen, DE

Re: A faster way for changing images?

Post by [-hh] » Tue Apr 19, 2016 2:14 am

Two notes to "computation speed" with the filter

1,1,1
1,1,1
1,1,1

[1] For this special filter you could leave out the (width x height x 3 x 9) multiplications by one. Then you have simple additions only.

[2] This filter is a "separable" one, splittable into
applying first the filter of

1,0,0
1,0,0
1,0,0

and then on the derived data apply the filter

1,1,1
0,0,0
0,0,0

Of course we then leave out the multiplications by zero in the code.
For large images and/or using the same filter with larger sizes N x N this could also increase speed by a factor of around N/2.

[Will certainly work on LC 6 and earlier, LC 7/8 will probably remain very slow.]
shiftLock happens

sanke
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 10
Joined: Tue Apr 11, 2006 7:31 pm
Location: Germany
Contact:

Re: A faster way for changing images?

Post by sanke » Tue Apr 19, 2016 9:51 am

I just got the sad information, that Christopher Lee Bodell, the author of "Photoroom", died already three years ago on January 17, 2013.
Birth: Jan. 28, 1990
Tillamook
Tillamook County
Oregon, USA
Death: Jan. 17, 2013
Seaside
Clatsop County
Oregon, USA
Christopher Lee Bodell
January 28, 1990-January 17, 2013
Christopher Lee ‘Chris' Bodell, 22, of Seaside,
died Thursday, Jan. 17, 2013, in Seaside.
Many thanks to the Livecode user who informed me.

The 17th of January, 2013, is also the last date of an access to his Forum Profile.

As I have referred, like others, to his "Photoroom" stack in one of my posts, I will discuss some aspects of "Photoroom" in more detail soon. His GUI and the general structure of the stack are of a high quality. He has even succeeded to implement and integrate an "undo/redo" function comprising 4 possible steps, a feature that I have not found so far in any other publicly available Livecode stack.

Wilhelm Sanke

Klaus
Posts: 13829
Joined: Sat Apr 08, 2006 8:41 am
Location: Germany
Contact:

Re: A faster way for changing images?

Post by Klaus » Tue Apr 19, 2016 12:17 pm

Hi Wilhelm,

thank you for this info!
This is very sad, damn, he was so young! :cry:


Best

Klaus

sanke
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 10
Joined: Tue Apr 11, 2006 7:31 pm
Location: Germany
Contact:

Re: A faster way for changing images?

Post by sanke » Tue Apr 19, 2016 8:01 pm

One of the factors we have to take into account when focusing on image processing speed in Livecode is the constantly increasing slowness when, for example, comparing LC versions 4 through 8. I have mentioned that several times last year on the dev and use-lists.

Of course there are other factors: CPU speed of course, different structures of the filters because of different purposes - there are others beside matrix-filters -, different scripting forms like arrays or repeat-for-each structures (which are not necessarily faster in quite a number of cases), and most importantly, to take calculations out of repeat structures as much as is possible.

For version LC 6 the greatest decline in speed is between LC 6.1.3 and LC 6.5.0, probably due to the new graphics layer:
Compare the Release Notes for LC 6.5.0
LiveCode 6.5.0 Release Notes 11/27/13
New Graphics Layer
The first step to supporting resolution independence was to completely refactor LiveCode's graphics layer. This involved writing and integrating an entirely new 2D graphics library that allows for scaled drawing. In addition to 2D graphic rendering, the library also handles text and image rendering. As such, nearly all aspects of LiveCode's drawing routines have been touched.

Since all of the updates are internal, the end LiveCode developer should see no major changes.
For quite a number of scripts when using LC 7.x and LC 8.x you need to substitute "byte" for "char". A script with a sequence of lines like these - part of a convolve script - would trigger a crash in LC 8 DP 15
put \\
numtochar(max(0,min((chartonum(char (ti1j -2) of timagedata)* tA1 + \
chartonum(char (ti1j +2) of timagedata)* tA2 +\
chartonum(char (ti3j +2) of timagedata)* tA8 + \
chartonum(char (ti3j +6) of timagedata)* tA9) \
/ tScale+tw,255))) into char (ti2j + 2) of tconvdata

To function properly in LC 8 DP 15 you would need
put \\
numtobyte(max(0,min((bytetonum(byte (ti1j -2) of timagedata)* tA1 + \
bytetonum(byte (ti1j +2) of timagedata)* tA2 \
bytetonum(byte (ti3j +2) of timagedata)* tA8 + \
bytetonum(byte (ti3j +6) of timagedata)* tA9) \
/ tScale+tw,255))) into byte (ti2j + 2) of tconvdata
and there is the special case for matrix calculations in some LC versions which need a "hybrid" form as in this scriptline to avoid an error message (I forget in this moment in which versions):

"chartonum(byte (ti1j +2) of timagedata)* tA2 +\".

Here is a list of speed comparisons using a very elementary script for an internal "mirror from right" (the right side of the image is mirrored on the left side) where no such char-byte substitutions are necessary:

MC 4.6.1 (with Metacard IDE)

320x240 640x480 1024x768 1600x1200

chars 113 305 730 1644
bytes 118 312 724 1672

==========================================
LC 4.6.1

320x240 640x480 1024x768 1600x1200

chars 170 519 1292 2973
bytes 168 512 1285 2967
=====================================================
LC 6.1.3

320x240 640x480 1024x768 1600x1200

chars 174 580 1381 3300
bytes 169 564 1381 3320
=========================================================

LC 6.5

320x240 640x480 1024x768 1600x1200

chars 1129 1525 2484 4550
bytes 1089 1489 2545 4411
================================================

LC 6.5.2

320x240 640x480 1024x768 1600x1200

chars 1480 1922 2938 4657
bytes 1452 1849 2936 4672
================================================
LC 6.7.10

320x240 640x480 1024x768 1600x1200

chars 1250 1694 2682 4393
bytes 1233 1285 2677 4412
================================================

LC 7.0.4

320x240 640x480 1024x768 1600x1200

chars 1215 1964 3694 6853
bytes 1273 1649 3257 5932
======================================

LC 7.1.3

320x240 640x480 1024x768 1600x1200

chars 1333 1849 3713 7004
bytes 1274 1865 3244 5831
=============================================

LC 8.0 DP 15

320x240 640x480 1024x768 1600x1200

chars 1347 2016 3677 6785
bytes 1289 1865 3271 6753
Here is the script used for the speed tests:

Code: Select all

> Here is an elementary example script for an internal "mirror from right" (the right side of the image is mirrored on the left side):

 "on mouseUp
   set the cursor to watch
   put the milliseconds into Start
   put the imageData of image x into iData
   put the height of img x into theight
   put the width of img x into twidth
   set the endvalue of scrollbar 1 to theight
   put trunc(theight/30) into scrollstep
   put 4* twidth into re
   put twidth/2 into twhalf
   repeat with i = 0 to theight - 1
     if i mod scrollstep = 0 then set the thumbpos of scrollbar 1 to i
     put i*re into ti
     put -1 into DiffJ
     repeat with j = twhalf to twidth - 1
       add 2 to DiffJ
       put char (ti + (j*4+2)) of idata into char (ti + ((j-DiffJ)*4 +2)) of idata
       put char (ti + (j*4+3)) of idata into char (ti + ((j-DiffJ)*4 +3)) of idata
       put char (ti + (j*4+4)) of idata into char (ti + ((j-DiffJ)*4 +4)) of idata
     end repeat
   end repeat
   set the imageData of image x to iData
   put the milliseconds - Start into fld "Test"
   set the thumbpos of scrollbar 1 to theight
 end mouseUp" 

Regards,

Wilhelm Sanke

[-hh]
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 2262
Joined: Thu Feb 28, 2013 11:52 pm
Location: Göttingen, DE

Re: A faster way for changing images?

Post by [-hh] » Wed Apr 20, 2016 12:15 am

Hello Wilhelm,

this is a very interesting documentation of speed loss.
[Although it is a bit mixed in loss by using the raw imageData and by displaying graphics (the progress).]

I changed your script (using bytes only) in steps, trying to win some speed.
  • Removed the time-consuming progress (scrollbar calls)
  • Tried to minimise the number of multiplications by using intermediate vars
    For example use put 4*j into j0 and using 9 times j0 instead of using 9 times 4*j
  • Tried to collect chunks of bytes where possible:
    put byte k to k+3 of iData into byte n to n+3 of iData
    instead of putting three times single bytes.
  • Added lock screen; lock messages
Each of these step wins some (significant) speed. I tested with a medium and large image size:
the first value is the timing for your script from above (changed to use bytes)
the second is the timing for my script below.

640x480 image Buchenberg:
1200 ... 300 ms -> speedFactor 4.0 ... LC 6.7.11-rc1
1200 ... 400 ms -> speedFactor 3.0 ... LC 7.1.4-rc1
1200 ... 500 ms -> speedFactor 2.4 ... LC 8.0.0-rc1

1600x1200 image Buchenberg:
1700 ... 600 ms -> speedFactor 2.8 ... LC 6.7.11-rc1
2200 ... 900 ms -> speedFactor 2.4 ... LC 7.1.4-rc1
2700 ... 1100 ms -> speedFactor 2.4 ... LC 8.0.0-rc1

[Machine used: Mac mini 2.5 GHZ i5, timing is averaged and rounded.]

Code: Select all

local x="IN", y="OUT"

on mouseUp
  put the milliseconds into strt
  lock screen; lock messages
  set cursor to watch
  if there is no img y then create img y
  put the imageData of image x into iData
  put the height of img x into theight
  put the width of img x into twidth
  put 4*twidth into re
  put trunc(twidth/2) into twhalf
  repeat with i = 0 to theight - 1
    put 1 + i*re into ti
    put -4 into DiffJ
    repeat with j = twhalf to twidth - 1
      add 8 to DiffJ; put ti + j*4 into j0
      put byte j0 to j0+3 of iData into \
            byte j0-DiffJ to j0-DiffJ+3 of iData
    end repeat
  end repeat
  set height of img y to theight
  set width of img y to 2*twHalf
  set imageData of image y to iData
  unlock screen; unlock messages
  set topleft of img y to 0,0
  put the milliseconds - strt into fld "Test"
end mouseUp
The image used (View from Buchenberg/ Germany) is attached, in medium quality because of the attachment size limit.

This is a wonderful effect! We're looking forward to your new ImageToolKit.

Regards, Hermann
Attachments
buchenbergMirror.jpg
View from Buchenberg, current effect applied
buchenberg640x480.jpg
View from Buchenberg/ Germany, JPEG 640x480
buchenberg1200x900.jpg
View from Buchenberg/ Germany, JPEG 1200x900
shiftLock happens

hairydalek
Posts: 57
Joined: Sat Feb 01, 2014 8:57 pm

Re: A faster way for changing images?

Post by hairydalek » Wed Apr 20, 2016 9:58 am

sanke wrote:Hi hairydalek,

I just provided you with the download address of my stack "ImageToolkitExperimental" by using your forum mail account.

Best regards,

Wilhelm Sanke
Thanks for doing this. While your stack can’t be opened in the Community Edition, I was able to put the code you wrote into a stack here and run it from there. It’s certainly faster than the code I was using.

I have moved on from using LIveCode to ImageMagick for image processing things though. I’m working on something that will create stereo card images, which immediately means that any image processing has to be done twice - one image per eye! Certainly with what I had, I was finding it a real problem from a usability point of view. If you are making edits and changes to an image, you expect the result to be fairly instant. On a 380x380 image, the time taken was painfully slow - and much slower on the final 300ppi output. ImageMagick is able to do that, and more (someone introduced me to the concept of colour look up tables - which means I can create Instagram type filters) at speeds I’m more comfortable with.

This does give me something to think about though.

[-hh]
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 2262
Joined: Thu Feb 28, 2013 11:52 pm
Location: Göttingen, DE

Re: A faster way for changing images?

Post by [-hh] » Wed Apr 20, 2016 3:25 pm

hairydalek wrote:...If you are making edits and changes to an image, you expect the result to be fairly instant. On a 380x380 image, the time taken was painfully slow - and much slower on the final 300ppi output. ImageMagick is able to do that...
Seen from LC user's view, ImageMagick is a collection of externals. A subset of these is optimized in graphicsMagick, which is much faster. Both are improved over years by nifty programmers. And both of these have also to work pixel by pixel...

If you now compare such externals in speed with LC you shouldn't take any LC script but the fastest available.
And you should measure the speed from input to output, the whole procedure.
When using imageMagick, you have to export an image to a file, get shell("<imageMagick script for file>") and to read in the imagefile with effects that was exported by imageMagick.

My experience is, that using imageMagick or even graphicsMagick is, of course, in most cases faster but NOT generally.

hh
p.s. As far as I can see, the possibilities of Wilhelm's Toolkit are NOT a simple subset of ImageMagick procedures.
shiftLock happens

sanke
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 10
Joined: Tue Apr 11, 2006 7:31 pm
Location: Germany
Contact:

Re: A faster way for changing images?

Post by sanke » Wed Apr 20, 2016 8:30 pm

Hi hairydalek,

You wrote
sanke wrote:
" I just provided you with the download address of my stack "ImageToolkitExperimental" by using your forum mail account."

Thanks for doing this. While your stack can’t be opened in the Community Edition, I was able to put the code you wrote into a stack here and run it from there. It’s certainly faster than the code I was using.
I have moved on from using LIveCode to ImageMagick for image processing things though.
This does give me something to think about though.
hairydalek
It is the protected substack "c-lib" that hinders Community versions to open the "Toolkit", although a great number of filters are not encrypted and open to inspection and use. The Livecode folks are really protective, aren't they? I have already thought about offering a free version for Community users. One argument against this was that the stack in its original form is more than 10 years old, and most parts of it have remained unchanged until now, meaning it needs an urgent "revamping" of structure and the overhaul of many of the filters.

In one of the worldwide Revolution gatherings - I think this was about 2005 - the toolkit had even been chosen as a paradigm for bad style and deficient design by a graphics expert in one of his presentations. I noticed this only later, when I received the conference DVDs. I have basically agreed to such an assessment, but had added in a response that there were some practical reasons for the "unusual"design to simplify the workflow and that the stack as a "toolkit preview" was very much still in an experimental stage. After that, the graphics expert (no offense intended here) and other users, among them Sivakatirswami from the hindu monastery on Kauwai, asked permissions to use some of the filters (protected and unprotected) like "blur" filters (there are several free ones of this type) or an "unsharp" filter (which was protected). I had declared at that point, that all unprotected filters could be freely used without asking for permission, and that I would give access to protected ones on demand. When later Chris Bodell found the "toolkit", he was naturally free to include convolve and other filters in his own stacks, and he did acknowledge this.

I need to stress here that quite a number of "my" filters are reverse-engineered filters gleaned from other sources and naturally needed to be adapted and slightly changed according to the settings of the Livecode language. Many of them are "Gluas" filters, written in the special "Lua"-dialect for the "Gimp" imagetool. I will also explain the origins of the 5 convolve-variants next time, where persons like Derek Bump, Chipp Walters, Thierry Douez, Bernd Niggemann, and Mark Waddingham either were authors of the first draft, or contributed significantly to the present form of the matrix script.

I have cooperated with Thierry Douez some time ago in developing a Lua-plugin for Livecode (Windows and Mac), i.e. I contributed on the basis of my experiences in adapting Gluas-scripts. He has mentioned this a few weeks ago:
Re: A faster way for changing images? (Feb 29, 2016)
Hi hairydalek,

Here is a project I did work on it a couple of years ago
with Wilhem Sanke.

http://sunny-tdz.com/sunnymage

Sadly, it is in a sleeping state.

Thierry

Thierrys convolve plugins work almost "instantly" even for large images, mostly equivalent in speed to the "Convolve.DLL" of Derek Bump, which however is restricted to 3x3 matrices, contains no "bias" factor, and sometimes simply doesn't work.

I think I will put up a free version of the "ImageToolkitExperimental" and give access to it on individual demand (still thinking). I personally use a number of newer image-processing and image-creating stacks (including such producing kinds of "computer art"), which are on a higher level effective, but still not in a publicly presentable state.-

I would be interesting for us, when you could continue to report about your experiences with ImageMagick .

Kind regards,

Wilhelm Sanke

sanke
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 10
Joined: Tue Apr 11, 2006 7:31 pm
Location: Germany
Contact:

Re: A faster way for changing images?

Post by sanke » Sat Apr 23, 2016 8:25 pm

I am relieved that I successfully passed the initiation rites and now can include URLs etc. in my posts. I had been told there are rules for newcomers to the Forum - at least 5 posts and waiting for 7 days - that could not even be overruled by an administrator. I could find nothing of that kind in the Forum Faqs, I think such rules should be spelled out there. Although rules exist to make life easier and more comprehensible, they more than often become obsolete and dogmatic, like, for example, with some religious rules that have been invented hundreds of years ago under totally different conditions of life. I am wondering why they should be applied to a user that was with Revolution and Livecode from the very beginning and is even proudly bearing a badge as a special VIP supporter of Livecode at the side of his posts. I recommend applying or updating rules more flexibly in the future.

Because "hairydalek" reported he could not open my ImageToolkit stack in Community versions I have produced and uploaded a "free" stack removing all script protections:


http://www.metaworx.net/ImageToolkitExp ... al-COM.rev


"COM" indicates that the stack can be also used with Community licenses. It has a volume of 20 MB. It will remain on the server at least for the time of our discussions in this thread and be available on demand later. I have tested this with a number of versions from LC 4.6.1 to LC 8.x. I did not test each script in all versions, it may be that some filters do not work in higher versions LC 7.x and LC 8.x, but this not yet happened to me. With versions LC 8.x you need to change the colors of menu button "specialties" to be able to read the menu. Remember, when you are using the stack in higher versions of Livecode to pay attention when you should save it. The best thing to do would probably be to copy the downloaded stack into the folder of the specific version of Livecode you wish to test it in.

I took me about three hours to produce the free version. I had removed all protections from the library stacks, but could not yet open the new stack in Community versions. Either when trying to "open" the stack there was no reaction at all from the IDE or I got a warning like this: "Stack may be corrupted - look for ~files", a very unspecific warning. I finally found out that there was another protected substack, but not being a library stack.

I will make a few comments about special features pertaining to our discussion in a later post. Keep in mind that it is a minimally changed stack more than 10 years old with a lot of deficiences and restrictions. But it surely gives an impression how you can creatively use Livecode even for image processing - having in mind what Richard Gaskin has remarked last year that "image processing surely is not one of the sweet spots of Livecode". I think that Livecode has the potential to offer ways of creative image manipulation that are not possible even with "Photoshop" and similar image tools. The most serious problem of Livecode, as I see it, is the constantly decreasing speed performance from lower versions (e.g. LC 4) to LC 8, which can not be fully balanced by more intelligent scripting. It is not understandable why Livecode should not be able to reach a performance level that it had already reached several years ago - it must be technically possible.

I do not intend to reap any revenues from my work with Livecode. Feel free to use any scripts in your own developments. I would be nice, if you find a feature for your use that does not have a similar counterpart elsewhere, to make a note of it.


Kind regards,

Wilhelm

sanke
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 10
Joined: Tue Apr 11, 2006 7:31 pm
Location: Germany
Contact:

Re: A faster way for changing images?

Post by sanke » Tue Apr 26, 2016 10:10 pm

Hairydalek had raised the question of how to apply blurs to images in this thread.
I found this post elsewhere in the forums:
"Can you blur an image?"
Post by William Jamieson » Thu Oct 15, 2015 4:38 am
.......However, I would like to know the most efficient way to blur images in our apps.
I first started with the livecode tutorial for this @http://lessons.runrev.com/m/4071/l/2658 ... r-an-image , but I could not find a version of LiveCode that could successfully complete the blur with a PC, let alone a poor old iPhone.
This LiveCode lesson first appeared in 2011 in one of the Livecode newsletters. The author was Hanson Schmidt-Cornelius who has written quite a number of articles in newsletters and Livecode blogs.

I put Hanson's code into one of my stacks and found that it was one of the slowest scripts I had encountered so far for creating image blurs, as if verifying Richard Gaskin's remark about "image processing not being one of the sweet spots of Livecode".
I created a stack with the ambiguous name "blurred vision" that contained 9 other scripts along with the recommended Livecode script for comparisons of speed, structure, and a variety of different blur effects and put the stack + comments ( see "read introduction") on my website. I have slightly changed the stack (the original ""Read introduction" text of 2011 has remained unchanged) and uploaded it to my newer domain

http://www.metaworx.net/BlurredVision-COM.rev

"COM" means that the stack is compatible with Community licenses, similar to my "ImageToolkitExperimental-COM" - to which I have added a few features in the meantime (the URL is the same as before).
Besides the blur scripts the BlurredVision stack contains a small number of "add-ons" for experimenting, like "random gradients", "seamless mirrors", "despeckle/median filters", a number of selected matrix filters, and "noise", "color change", and an "auto gamma" function.
There are 6 images to choose from and there is a "load image" button to import own images.

I have compared speeds for the 10 blur version between LC 4.6.1 (with MC IDE) and LC 7.1.3. The results for an image 640x480 on a Windows 7 computer
MC 4.61

"Livecode lessons blur" : 28437 ms (28 seconds)

"blur horizontal" 1184 ms as the fastest speed

LC 7.1.3

"Livecode lessons blur" : 83419 ms (83 seconds)

"blur horizontal" 3185 ms
The resulting blurs from the two filters are almost identical.
I left out the progress bars this time, so you need some patience when waiting for the scripts to finish. When you take a look at the scripts, I have the impression that the Livecode-lessons script has a number of traits of C-programming and less of genuine Livecode structures.

Kind regards,

Wilhelm

sanke
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 10
Joined: Tue Apr 11, 2006 7:31 pm
Location: Germany
Contact:

Re: A faster way for changing images?

Post by sanke » Mon May 02, 2016 9:59 pm

Immediately after uploading the "BlurredVision" stack on April 26 to

http://www.metaworx.net/BlurredVision-COM.rev

I had noticed that the char-byte arrangement in the matrix-convolve scripts did not allow to run the stack in *all* LC versions from LC 4.6.1 to 8.x. I corrected this some hours after uploading, and the correction is included since then.
To illustrate what I corrected, I use the following script snippet from a convolve script as an array function. Bernd Niggemann will detect traits of his preferences for array solutions:

Code: Select all

>  put \\
>           numtobyte(max(0,min((chartonum(byte (p-8) of treData2) * tA1 +\
>           chartonum(byte (p-4) of treData2) * tA2+\
>            ..............etc.............................
>           chartonum(byte (p+4) of treData6) * tA24+\
>           chartonum(byte (p+8) of treData6) * tA25)\
>           / tScale+tw,255))) into tRed
The script here contains the sequence "*numtobyte-chartonum-byte*". The wonderful effect of this combination is that it works without throwing errors in all LC versions from 4.6.1 to 8.x. This kind of a convolve script runs 3.54 times slower in LC 8 than in LC 4.6.1 irrespective of the image size and it is also the fastest of the char-byte permutations "*numtochar-chartonum-char*", "*numtobyte-chartonum-byte*", and "*numtobyte-bytetonum-byte*".

Measured with an image 640x480 in LC 8 "*numtobyte-chartonum-byte*" runs about 2 seconds faster than with the combination "*numtobyte-bytetonum-byte*".

"*numtobyte-bytetonum-byte*" produces instant crashes in LC 4.6.1.

"*numtochar-chartonum-char*" throws errors in LC 6 (and before) and crashes the earlier versions of LC 7.x, but is accepted - meaning it does not throw errors or produce crashes - in later LC 7 and all LC 8 versions, but is however tremendously (or rather to be expected because of the general char-byte change) slower in LC 7 and LC 8. The speed difference can only be measured with small image sizes.

Results measured in LC 8 between combinations "*numtobyte-chartonum-byte*" and "*numtochar-chartonum-char*":
- image size 160 x 120 = 13.49 times slower
- image size 320 x 240 = 76.28 times slower
- image size 480 x 360 = 547.03 times slower
It takes about 45 minutes with size 480 x 360 and numtochar-chartonum-char compared to 5 seconds using numtobyte-chartonum-byte (on my Windows 7 computer).

The "same" image with differing sizes was used for the measurements, i.e. the text of an image (2048 x 1536) was imported into the teststack, stored in a CP and is then ready for display in 8 different sizes for testing. This ensures that the average of all sum(RGB) pixels remains the same across all sizes. Brighter pictures take a few milliseconds longer than darker ones.

No progress bars were used in the tests, which however produce only insignificant speed differences, as I have measured them under multiple conditions.

The filter used for the tests was an "unsharp mask 5x5" filter. The same kind of script and the same matrix values were used for all measurements, the only exception being the change from the "numtobyte-chartonum-byte" to the "numtochar-chartonum-char" sequence.

Script structure is also a factor that can result in speed differences. An extreme example for this is the Livecode-lessons blur script which is 28 times slower than the fastest of my blur filters contained in the BlurredVision stack, meaning also that the very same filter effect can be achieved by totally different script structures and speeds. However, when comparing both of these blur scripts in LC 4.6.1 and LC 8 the basic speed difference of 3.5 times between versions remains - because of the different image-processing algorithms in the engines of LC 4.6.1 and LC 8.

Next time I intend to address again the issue of "spatial" filters, where the RGB-values of the individual pixels - other than with matrix-convolve filters - remain unchanged and the pixels are only "relocated" inside the image, an example being the "mirror from right"-script we have already discussed in the contributions to this thread on April 19.

Kind regards,

Wilhelm Sanke

Post Reply

Return to “Multimedia”