A faster way for changing images?
Moderators: FourthWorld, heatherlaine, Klaus, kevinmiller, robinmiller
-
- Posts: 57
- Joined: Sat Feb 01, 2014 8:57 pm
A faster way for changing images?
HI,
I’m looking at the PhotoRoom suite from Chris Bodell to add some image processing facilities to my application. The thing is that it’s so very slow. For example, I’m providing a check box to make an image sepia. On a 380x380 image, it takes not seconds but minutes to make this change. Sure, it’s got 144400 pixels to work through, but it’s painful. One. Pixel. At. A. Time. I thought a progress bar at least would add some feedback which may help, but not really. The idea is that you’d be working on a preview - a small “model” of the final output, so changes like this should be fairly instant. As this is a stereo card application, the processing has to be done twice - once for the left image, and once for the right image.
It would take much, much longer when the image is processed for final print resolution output (and, no, I’ve not tried that yet).
Is there a quicker (cross platform) way to add image effects - things like contrast, brightness, colour tinting etc. so when you drag a slider or click a check box, things happen instantly (or at the very least quickly enough to be useful)? I think the user would not mind being kept a couple of minutes or so for a final print ready image, but for an on screen proxy what I have right now is really not good at all.
I’m looking at the PhotoRoom suite from Chris Bodell to add some image processing facilities to my application. The thing is that it’s so very slow. For example, I’m providing a check box to make an image sepia. On a 380x380 image, it takes not seconds but minutes to make this change. Sure, it’s got 144400 pixels to work through, but it’s painful. One. Pixel. At. A. Time. I thought a progress bar at least would add some feedback which may help, but not really. The idea is that you’d be working on a preview - a small “model” of the final output, so changes like this should be fairly instant. As this is a stereo card application, the processing has to be done twice - once for the left image, and once for the right image.
It would take much, much longer when the image is processed for final print resolution output (and, no, I’ve not tried that yet).
Is there a quicker (cross platform) way to add image effects - things like contrast, brightness, colour tinting etc. so when you drag a slider or click a check box, things happen instantly (or at the very least quickly enough to be useful)? I think the user would not mind being kept a couple of minutes or so for a final print ready image, but for an on screen proxy what I have right now is really not good at all.
-
- Livecode Opensource Backer
- Posts: 9293
- Joined: Fri Feb 19, 2010 10:17 am
- Location: Bulgaria
Re: A faster way for changing images?
I think you really should have a good look at Blend/Ink and Graphic effects:
https://www.dropbox.com/s/7uy006ugwjmxh ... e.zip?dl=0
This is what I managed in about 10 minutes!
https://www.dropbox.com/s/7uy006ugwjmxh ... e.zip?dl=0
This is what I managed in about 10 minutes!
-
- VIP Livecode Opensource Backer
- Posts: 7216
- Joined: Sat Apr 08, 2006 8:31 pm
- Location: Minneapolis MN
- Contact:
Re: A faster way for changing images?
Are you working with the imageData in RAM? Changing pixels directly in the image itself is going to take much longer.
There was a lesson about doing this kind of thing that could help:
http://lessons.livecode.com/m/4071/l/12 ... processing
There was a lesson about doing this kind of thing that could help:
http://lessons.livecode.com/m/4071/l/12 ... processing
Jacqueline Landman Gay | jacque at hyperactivesw dot com
HyperActive Software | http://www.hyperactivesw.com
HyperActive Software | http://www.hyperactivesw.com
-
- Posts: 57
- Joined: Sat Feb 01, 2014 8:57 pm
Re: A faster way for changing images?
Thanks, all. This is very interesting , and I've been doing some digging myself. I have found a site that has some examples, and pseudo code that may be helpful: http://www.dfstudios.co.uk/articles/pro ... lgorithms/
You still have to go through a pixel at a time, but maybe if I rolled my own, I can speeed things up a bit.
Richmond62 - thanks. It would be helpful if you could post an example showing how you got to a result. I'm not asking you to write everything for me, but something to act as a sign post for me would probably be enough. I've tried searching for ink and blends in relation to LiveCode, but there's not a huge amount of information out there that helps, I'm afraid.
I'll keep digging, and experimenting as well when I have the time (this isn't my day job), so I may stumble across something myself.
You still have to go through a pixel at a time, but maybe if I rolled my own, I can speeed things up a bit.
Richmond62 - thanks. It would be helpful if you could post an example showing how you got to a result. I'm not asking you to write everything for me, but something to act as a sign post for me would probably be enough. I've tried searching for ink and blends in relation to LiveCode, but there's not a huge amount of information out there that helps, I'm afraid.
I'll keep digging, and experimenting as well when I have the time (this isn't my day job), so I may stumble across something myself.
-
- Livecode Opensource Backer
- Posts: 9293
- Joined: Fri Feb 19, 2010 10:17 am
- Location: Bulgaria
Re: A faster way for changing images?
I suggest you start by downloading my stack, then opening the properties
palette and looking at "Blend" and "Graphic Effects" for each image.
palette and looking at "Blend" and "Graphic Effects" for each image.
-
- Posts: 57
- Joined: Sat Feb 01, 2014 8:57 pm
Re: A faster way for changing images?
Oh - sorry! I was looking for scripts. I didn’t think to look at the properties. What a dullard! Thanks!richmond62 wrote:I suggest you start by downloading my stack, then opening the properties
palette and looking at "Blend" and "Graphic Effects" for each image.
-
- Posts: 57
- Joined: Sat Feb 01, 2014 8:57 pm
Re: A faster way for changing images?
Continuing with this - what’s been posted has been helpful, but hasn’t answers all my problems. Achieving effects such as blurs, adding noise, and manipulating contrast seems to require code that steps through an image pixel by pixel. This means that if you are using a slider to alter the amount of that effect, you can’t provide live feedback in the form of a preview, and you need to wait a long time for the image to process when the slider drag has ended. A very long time if we are talking about blurs. Tea-making lengths of time. If someone then decides to alter the size of the image, change its crop, the processing has to be repeated.
The problem is that processing a 380x380 image takes ages. That’s not a very big image by today’s standards (yes, yes, lots of data, but this on a modern machine on a modern OS - not a machine from 1987). If you are aiming at putting out an image for print (my 380x380 is a proxy image in a design environment - the final image will be 3 times that size) you can be waiting a much longer time. Also, as this is stereo imagery I’d processing, that’s two images - left and right. So double your times.
Note that 380 is the minimal size of the images - they can get larger if the user wants.
So I take it that LiveCode has no image processing facilities that can handle this kind of manipulation at a more acceptable speed? It’s frustrating. I was hoping to provide a snappier experience. I’m not expecting to write a Photoshop killer, but I’d like to be able to have reasonable response times.
The problem is that processing a 380x380 image takes ages. That’s not a very big image by today’s standards (yes, yes, lots of data, but this on a modern machine on a modern OS - not a machine from 1987). If you are aiming at putting out an image for print (my 380x380 is a proxy image in a design environment - the final image will be 3 times that size) you can be waiting a much longer time. Also, as this is stereo imagery I’d processing, that’s two images - left and right. So double your times.
Note that 380 is the minimal size of the images - they can get larger if the user wants.
So I take it that LiveCode has no image processing facilities that can handle this kind of manipulation at a more acceptable speed? It’s frustrating. I was hoping to provide a snappier experience. I’m not expecting to write a Photoshop killer, but I’d like to be able to have reasonable response times.
Re: A faster way for changing images?
Hi hairydalek,
Here is a project I did work on it a couple of years ago
with Wilhem Sanke.
Sadly, it is in a sleeping state.
Thierry
Here is a project I did work on it a couple of years ago
with Wilhem Sanke.
Sadly, it is in a sleeping state.
Thierry
Last edited by Thierry on Thu Nov 17, 2022 12:29 pm, edited 1 time in total.
!
SUNNY-TDZ.COM doesn't belong to me since 2021.
To contact me, use the Private messages. Merci.
!
SUNNY-TDZ.COM doesn't belong to me since 2021.
To contact me, use the Private messages. Merci.
!
-
- VIP Livecode Opensource Backer
- Posts: 9804
- Joined: Sat Apr 08, 2006 7:05 am
- Location: Los Angeles
- Contact:
Re: A faster way for changing images?
You have discovered a use case for which most scripting language are of limited utility.hairydalek wrote:Achieving effects such as blurs, adding noise, and manipulating contrast seems to require code that steps through an image pixel by pixel. This means that if you are using a slider to alter the amount of that effect, you can’t provide live feedback in the form of a preview, and you need to wait a long time for the image to process when the slider drag has ended. A very long time if we are talking about blurs. Tea-making lengths of time. If someone then decides to alter the size of the image, change its crop, the processing has to be repeated.
For effects LiveCode has built-in support for which was written in C, we have the pleasure of invoking that with nearly instantaneous results. These currently include opacity, inner glow, outer glow, color overlay, transfer modes, drop shadows, and others.
But there are still some image manipulations. like blur and noise, which do not have C-borne code in the engine, and so like any other scripting language the ovehead of doing such low-level work in a high-level language will add up quickly with larger images.
If you search the request queue for "image" you'll find a variety of enhancement requests for various things, but one which may be most useful I was unable to find there: a generic convolver.
I haven't done much image processing myself so forgive me if my ignorance shows, but it seems many of the operations we'd like to do not already supported could be handled through a convolver, and the problem being that applying a matrix change to the full set of pixels in script is currently computationally prohibitive in script.
But if we have something like a convolve function, which could take a matrix of deltas and a set of image data and return the image data altered according to that matrix, because most of the work would be done in C it should be very efficient while still being reasonably flexible.
If that hunch is correct, perhaps we could put together a bounty so someone in the community might consider adapting publicly-available code for this to LC. At a minimum it could be an external, but even better if it became a pull request for an engine feature.
I believe a convolver would handle noise, but would it handle blur as well?
Richard Gaskin
LiveCode development, training, and consulting services: Fourth World Systems
LiveCode Group on Facebook
LiveCode Group on LinkedIn
LiveCode development, training, and consulting services: Fourth World Systems
LiveCode Group on Facebook
LiveCode Group on LinkedIn
-
- Posts: 57
- Joined: Sat Feb 01, 2014 8:57 pm
Re: A faster way for changing images?
Thanks. Yes, I get the difference between scripting and working in languages like C (similar relationship to BASIC and assembler on my trusty old BBC B) - though the latter (in both cases) is beyond me. I don’t fully understand how convolving filters work, though I have been reading up on blurs and other filters in order to see if I can grasp what’s needed, and that’s helping improve my understanding a bit. There’s one where the writer asks if he needs a haircut and uses image processing to determine that, and there are other tutorials which have helped. I also found some reference with pseudocode that helped me put greyscale and contrast adjustments together, but, as you’ll guess, they are all a pixel by pixel walk-through in LC’s scripting language. http://www.dfstudios.co.uk/articles/pro ... lgorithms/FourthWorld wrote:You have discovered a use case for which most scripting language are of limited utility.hairydalek wrote:Achieving effects such as blurs, adding noise, and manipulating contrast seems to require code that steps through an image pixel by pixel. This means that if you are using a slider to alter the amount of that effect, you can’t provide live feedback in the form of a preview, and you need to wait a long time for the image to process when the slider drag has ended. A very long time if we are talking about blurs. Tea-making lengths of time. If someone then decides to alter the size of the image, change its crop, the processing has to be repeated.
For effects LiveCode has built-in support for which was written in C, we have the pleasure of invoking that with nearly instantaneous results. These currently include opacity, inner glow, outer glow, color overlay, transfer modes, drop shadows, and others.
But there are still some image manipulations. like blur and noise, which do not have C-borne code in the engine, and so like any other scripting language the ovehead of doing such low-level work in a high-level language will add up quickly with larger images.
If you search the request queue for "image" you'll find a variety of enhancement requests for various things, but one which may be most useful I was unable to find there: a generic convolver.
I haven't done much image processing myself so forgive me if my ignorance shows, but it seems many of the operations we'd like to do not already supported could be handled through a convolver, and the problem being that applying a matrix change to the full set of pixels in script is currently computationally prohibitive in script.
But if we have something like a convolve function, which could take a matrix of deltas and a set of image data and return the image data altered according to that matrix, because most of the work would be done in C it should be very efficient while still being reasonably flexible.
If that hunch is correct, perhaps we could put together a bounty so someone in the community might consider adapting publicly-available code for this to LC. At a minimum it could be an external, but even better if it became a pull request for an engine feature.
I believe a convolver would handle noise, but would it handle blur as well?
If by a convolver you mean “pass a matrix of values to a function that processes an image using it” then it seems that, yes, blurs are possible:
http://lodev.org/cgtutor/filtering.html
That page shows that sharpening, embossing and other effects are possible. I need to study that a bit more. I’ll have a stab at writing my own LC function to process and image from a matrix. I know it will be slow, but the exercise may be helpful to me. Being able to pass data to a function in LC and get back results faster would, of course, be far better and make the application much more efficient.
I’ll explain a little about my thinking for what I am working on, just so you know where I’m coming from.
I know what I can do in Photoshop to achieve an effect, and if I don’t know, I know where to look for examples. I am trying to replicate those kind of things in LiveCode. I went from thinking about applying fairly simple effects like contrast, greyscale and brightness (slow, but bearable) to pondering creating effects similar to Instagram and other apps. Basically, applying what in Photoshop is referred to as “filters” (blur, noise, etc.), colour tints, or just overlaying an image with a colour gradient, layering them and grabbing the output.
For example, to create a Holga style lens effect, you do this:
1 - Get your original image, duplicate it and place the duplicate over the top of the original
2 - Apply a radial blur to the image. I’m not sure how you’d achieve this using the convolution method above. I guess a regular of gaussian blur may be sufficient, but Holga lenses do do weird distortions which the radial blur emulates better.
3 - Using an alpha channel, make the blurred image transparent at the middle and gradually increase the opacity towards the edges
4 - (Optional) Greyscale and contrast applied to both images
If you want a more detailed step by step for this example, this tutorial is what I was thinking about:
https://lenscraft.co.uk/how-to-digitall ... lga-image/
I know how to do this in LiveCode, and (apart from the radial blur - I’d use a standard blur for the moment) I expect I can get the effects I want. Right now, as you know, it’s a time penalty that’s thwarting me.
It’s a hideous case of “function creep” but this project started off as a “can I” question as I’ve not done much in LiveCode, and so far I’ve been able to answer with a “yes”. As I progress, more questions arise.
I am writing an application that processes images shot with a digital stereo camera and makes them into a printable Holmes Card (a popular way of presenting stereo photos from Victorian times). There are a few apps around that do this already, but I’m finding them limiting. I want to be able to do more in the application, rather than duck out into Photoshop, or make various design choices about the card itself that other apps don’t offer. So I decided to have a go myself. It’s a personal project at the moment, but slowly developing a life of its own. It’s been a fun thing to attempt, and I’ve learned quite a bit about LiveCode (and, indeed a small bit about image processing).
-
- VIP Livecode Opensource Backer
- Posts: 9804
- Joined: Sat Apr 08, 2006 7:05 am
- Location: Los Angeles
- Contact:
Re: A faster way for changing images?
That sounds way cool. I love stereoscopy - please post a link to your app when it's available.hairydalek wrote:I am writing an application that processes images shot with a digital stereo camera and makes them into a printable Holmes Card (a popular way of presenting stereo photos from Victorian times).
Richard Gaskin
LiveCode development, training, and consulting services: Fourth World Systems
LiveCode Group on Facebook
LiveCode Group on LinkedIn
LiveCode development, training, and consulting services: Fourth World Systems
LiveCode Group on Facebook
LiveCode Group on LinkedIn
-
- Posts: 57
- Joined: Sat Feb 01, 2014 8:57 pm
Re: A faster way for changing images?
Will do. I've still got a list of ideas to work on, and it's rather part time. It's fascinating - I have some old stereo cards as well as ones photos I've taken myself.FourthWorld wrote:That sounds way cool. I love stereoscopy - please post a link to your app when it's available.hairydalek wrote:I am writing an application that processes images shot with a digital stereo camera and makes them into a printable Holmes Card (a popular way of presenting stereo photos from Victorian times).
I have managed to get a convolution command written which seems to do the job. I know it's re-inventing the wheel, but the exercise was good. You can pass a matrix in an array that gets applied to the image. It's still slow, but I feel a sense of achievement having done it.
-
- VIP Livecode Opensource Backer
- Posts: 9804
- Joined: Sat Apr 08, 2006 7:05 am
- Location: Los Angeles
- Contact:
Re: A faster way for changing images?
At the SoCal Linunx Expo a few weeks ago we had a mini museum of older technologies set up as part of Game Night, and among the wonderful old Sun and NeXT computers someone also brought some great vintage stereo slides and viewers:
https://plus.google.com/u/0/+RichardGas ... 6UCxQVLYE3
https://plus.google.com/u/0/+RichardGas ... 6UCxQVLYE3
Richard Gaskin
LiveCode development, training, and consulting services: Fourth World Systems
LiveCode Group on Facebook
LiveCode Group on LinkedIn
LiveCode development, training, and consulting services: Fourth World Systems
LiveCode Group on Facebook
LiveCode Group on LinkedIn
-
- Posts: 57
- Joined: Sat Feb 01, 2014 8:57 pm
Re: A faster way for changing images?
Those look good. I hope you were able to use the viewers to look at the cards. You can't take something like that along to a meeting and not share the experience with others.FourthWorld wrote:At the SoCal Linunx Expo a few weeks ago we had a mini museum of older technologies set up as part of Game Night, and among the wonderful old Sun and NeXT computers someone also brought some great vintage stereo slides and viewers:
https://plus.google.com/u/0/+RichardGas ... 6UCxQVLYE3
-
- Posts: 57
- Joined: Sat Feb 01, 2014 8:57 pm
Re: A faster way for changing images?
I thought I’d share what I have at the moment. I’ve written my own “convolving” processor in LiveCode. I thought that if I did it I would understand better what was involved, and also it was an exercise in processing images a bit more. I’ve not sped it up much, but I’ve found a fairly decent place in the code to drop a progress bar. Updating one every time a pixel is interrogated really did slow it down, but at the moment I’ve got it updating after each row of pixels. I may step that to after every 10 rows, just for good measure. I want to indicate to the user that things will take some time to process.
Anyway, here’s the function (without progress bar stuff). I apologise for my coding in advance. It probably looks clunky:
To use this, you need to set up the matrix and give it an image to process:
This will do a simple blur. The parameters passed to the convolve function are:
pImage - the long id of an image
myMatrix - a matrix containing the transform for each pixel - the more items in the matrix, the slower the processing will be.
divider - how much to divide the sum of the RGB values for each pixel in the image. In my travels, I’ve found that the total of the numbers in the matrix needs to add up to 1 - (some even use fractions or decimals), but usually this seems to be achieved by using whole numbers and dividing by the number of elements. However, I have come across some effects where the divider has been different to the element count, so I decided to allow that to be specified separately.
The notion of building a coarse view for preview sake, and going to full quality for the final output crossed my mind, but it won’t be very WYSIWYG. It would speed up the whole process though. I need to think about this some more.
EDIT: I am reminded of an application I had for my Mac many, many years ago. It came from Macromedia and was called XRes. It was a Photoshop-like application and it attempted to overcome the long processing times by giving you a screen proxy to work on. So you could apply complex filters with the time taken to process the image limited to the pixels on screen. If you zoomed in or out, or saved, then all the operations that were proxied were applied to the full version of the image. That would be the time to take a break, but it did mean that you could do a lot of work without the constant progress bars that Photoshop imposed. On Macs from that era (mine was a PowerBook 1400), you really could save time if you worked smart with that application.
Anyway, here’s the function (without progress bar stuff). I apologise for my coding in advance. It probably looks clunky:
Code: Select all
command convolve pImage,myMatrix,divider
put the number of elements of myMatrix into myRows
repeat for each key myKey in myMatrix
split myMatrix[myKey] by comma
end repeat
put the number of elements of myMatrix[1] into myColumns
put trunc(myRows/2) into rowStart
put trunc(myColumns/2) into colStart
-- Load variables with image data
put the imageData of pImage into tData
put empty into tData2
put the width of pImage into pWidth
put the height of pImage into pHeight
put numToChar(255) into tAlpha
repeat with y = 1 to pHeight
repeat with x = 1 to pWidth
put 0 into tRed
put 0 into tGreen
put 0 into tBlue
put 1 into factorX
put 1 into factorY
-- Now to loop through the x and y of the matrix
repeat with tRow = y-rowStart to y+rowStart
repeat with tColumn = x-colStart to x+colStart
put myMatrix[factorY][factorX] into factor
put ((tRow-1) * pWidth * 4 ) + ((tColumn-1) * 4) into position
put (charToNum(char position + 2 of tData)*factor) + tRed into tRed
put (charToNum(char position + 3 of tData)*factor) + tGreen into tGreen
put (charToNum(char position + 4 of tData)*factor) + tBlue into tBlue
put factorX+1 into factorX
put progressCounter +1 into progressCounter
end repeat
put factorY+1 into factorY
put 1 into factorX
end repeat
put numToChar(255) after tData2
put numToChar(tRed / divider) after tData2
put numToChar(tGreen / divider) after tData2
put numToChar(tBlue / divider) after tData2
end repeat
end repeat
-- Put image data back into the image
set the imageData of pImage to tData2
end convolve
Code: Select all
put "1,1,1" into myData[1]
put "1,1,1" into myData[2]
put "1,1,1" into myData[3]
put long id of image "image to process" into myImage
lock screen
convolve pImage,myData,9
unlock screen
pImage - the long id of an image
myMatrix - a matrix containing the transform for each pixel - the more items in the matrix, the slower the processing will be.
divider - how much to divide the sum of the RGB values for each pixel in the image. In my travels, I’ve found that the total of the numbers in the matrix needs to add up to 1 - (some even use fractions or decimals), but usually this seems to be achieved by using whole numbers and dividing by the number of elements. However, I have come across some effects where the divider has been different to the element count, so I decided to allow that to be specified separately.
The notion of building a coarse view for preview sake, and going to full quality for the final output crossed my mind, but it won’t be very WYSIWYG. It would speed up the whole process though. I need to think about this some more.
EDIT: I am reminded of an application I had for my Mac many, many years ago. It came from Macromedia and was called XRes. It was a Photoshop-like application and it attempted to overcome the long processing times by giving you a screen proxy to work on. So you could apply complex filters with the time taken to process the image limited to the pixels on screen. If you zoomed in or out, or saved, then all the operations that were proxied were applied to the full version of the image. That would be the time to take a break, but it did mean that you could do a lot of work without the constant progress bars that Photoshop imposed. On Macs from that era (mine was a PowerBook 1400), you really could save time if you worked smart with that application.