if you have ever used adobe lightroom you would have noticed that there is an awesome sidebar with 15 or so sliders on it. they can all be adjusted from the same screen and you watch as they edit the image in real time. This is what I am trying to replicate. and here is where my problem lies...

I have written some methods that apply color matrices to an image and return that transformed image. works great. i can put a slider on drag the tick and watch the brightness change ect. but in order for the transformation to be accurate, I must always pass the source image to each one. not the edited image. let me elaborate.

say I increase the brightness and contrast of an image using a complicated color matrix. but now i want to increase the saturation a bit, so i pass the new adjusted image into my hsl class and return a new image, now the image has been changed twice. If I feel like the image is too bright, and I want to move the brighness slider down. I the value assigned to the slider will be wrong, and its effects not accurate using the newly edited image, I must use the original image. so that means I must store and reapply the saturation values, but this means, given all the adjustments my final program will be using will have to be applied every time, this will be sluggish, and not a instant preview like lightroom provides.

Is there something I am missing? Am I going about his wrong?

I don't want it to be like photoshop, where a change is permanent. I want the lightroom type experience where everything can be changed and reset easily.

Recommended Answers

All 8 Replies

Unless Adobe are using magic, it is simply a memory/cpu tradeoff.

1. CPU Hungry - Store 1 raw image & 1 changed image, apply all changes every time a single change is made.

2. Memory hungry - Store 1 copy to be displayed & 1 copy for every transformation. Each transformation imjage should be the effective raw image for that one transformation & so should have all of the other transformations already applied. That way when you make one change to hue when you have already changed brightness, it uses an image with the brightness already changed so it only has to do the one image manipulation process.
Then i'd imagine the clever people at adobe will cap cpu usage of 'background' updates and do the updates to the other images in memory in the background (perhaps one thread instead of two or four). - Keeping the program feeling responsive.

The second way reduced the processing that has to be done in realtime for the image to be displayed to the user, but the processing will still have to be done in the background nonetheless.

Ultimately there is no such thing as magic with computers :( Only logic :)

I think lightroom might be magic, as it has 60 sliders ( I counted them just now) and all of them are live, real time instant display of change, even a live histogram that changes with the sliders. And thats on a 32mb digital negative 32 bit image over 4000px wide taken with a Nikon SLR cam. idk how they do it. But I managed to create a color matrix that handles brighness, saturation, and contrast simultaneously and its not blazing fast, but its almost real time. so if I could just come up with a smoothing/sharpening effect that is semi-real time. with what I have, I would be satisfied. Kudos to the adobe lightroom team. after all my research, I have found nothing of how they do it.

How does your actual code function though? Using the managed API for working with images is very slow. As far as I know you have to use unsafe regions of code to directly edit an image in-place. You would also want to implement threading in your application. I'm thinking if you have an original image -- say 300x300 -- then you would malloc the image matrix twice. Once for the original, once for the working copy. When you apply a change you would read the value from the original and apply it to the working copy. You would probably not want to free the memory from the old image and instantiate a new one as this would slow things down, you want to directly get the memory address and start changing values on the fly.

I am applying a colormatrix object as an imageattribute to drawimage. which requires a new image everytime, and reading the source image everytime.

I have a method that takes a source image, and the 3 values of each slider, creates a single color matrix from that data creates a bitmap image, draws to it the originonal image with the colormatrix image attribute, then returns that image. the image is set to a picturebox and the picturebox is refreshed.

given that situation how could I improve?

I don't know off hand. You need to find a way to work with the image in place to gain any sort of performance though. Constantly malloc'ing a new image and freeing the old one up for GC will eat resources bad. I'm not much use when it comes to graphics i'm afraid :(

I tried this
when the image loads in, create a WorkingImage that is 1/4 the size or so, display that image scaled to fit in the image viewer picturebox. then use that image for the transformations preview it is much faster, and either wait to apply the transformations to the full image until the image is saved, or alternatively, like in my application where you might need the transformed full image, periodically update a fullsized transformed image on a separate thread.

Sill working the bugs out, but it seems to give that performance burst that makes everything feel fluid.

good thinking! If you are only displaying a reduced size preview of the transformations, why use up system resources applying changes to the full size image.
Cant wait to see how your finished project runs :)

since I am using a zoomed picturebox, the resulting appearance is identical. I am using that crop picture box i was working on, that allows you to go back and fourth between the cropped and uncropped image, and proper cropping requires the real full size image, unless I want it to only be approximate. So I'm looking into a work around for the issues it creates. And also I am looking to expand that cropped picturebox control to support zoomed, 1:1 and maybe 1:3 viewing sizes with the ability to pan, That's a whole new ball game there. Like I said, its a really ambitious project. But once its done, Hopefully it will be a worthwhile adventure. So many features to implement.

Thanks again, expect to see a few more threads pop up from me as the program carries on in development.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.