VB.NET School Assignment? Project Due Tomorrow? Chat LIVE With A Programming Expert!

Welcome to Dream.In.Code
Become a VB.NET Expert!

Join 300,404 VB.NET Programmers for FREE! Get instant access to thousands of VB.NET experts, tutorials, code snippets, and more! There are 1,611 people online right now. Registration is fast and FREE... Join Now!




Red Color of one image to the Alpha value of the second

 

Red Color of one image to the Alpha value of the second

abedjoud

30 Jun, 2009 - 01:00 PM
Post #1

New D.I.C Head
*

Joined: 11 Jun, 2009
Posts: 16



Thanked: 1 times
My Contributions
Hello Readers...
I am trying to create a function that would take 2 images. 1 of the images is a grayscale image and the other is a normal image. What i want to do is apply any of the R or G or B of the grayscale image (in grayscale image r=g=b so it makes no difference) to the Alpha of the second image. i DID succeed on it. However the code is EXTREMELY slow. It takes 1 second to perform it. And i have to perform the function atleast 30 times a second (it will be outputting to a Decklink card).
Here is the code:
CODE

public function createOverlay(ByVal Main as Bitmap, ByVal Key as Bitmap) as Bitmap
For index as integer =0 To (Key.Width*Key.Height)-1
Dim crntX= index Mod(Key.Width)
Dim crntY=Math.Floor(index/Key.Width)
Dim oldColor= Main.GetPixel(crntX,crntY)
Main.SetPixel(crntY,crntX,Color.FromArgb(Key.GetPixel(crntX,crntY).R,oldColor.R,oldColor.G,oldColor.B))
Next
End Function


This function will have to run infinitley until the user presses stop and keep updating the output buffer. How can i make it faster? ( i need at least 30 executions per second)

Thanks

User is offlineProfile CardPM
+Quote Post


abedjoud

RE: Red Color Of One Image To The Alpha Value Of The Second

1 Jul, 2009 - 02:59 PM
Post #2

New D.I.C Head
*

Joined: 11 Jun, 2009
Posts: 16



Thanked: 1 times
My Contributions
QUOTE(abedjoud @ 30 Jun, 2009 - 01:00 PM) *

Hello Readers...
I am trying to create a function that would take 2 images. 1 of the images is a grayscale image and the other is a normal image. What i want to do is apply any of the R or G or B of the grayscale image (in grayscale image r=g=b so it makes no difference) to the Alpha of the second image. i DID succeed on it. However the code is EXTREMELY slow. It takes 1 second to perform it. And i have to perform the function atleast 30 times a second (it will be outputting to a Decklink card).
Here is the code:
CODE

public function createOverlay(ByVal Main as Bitmap, ByVal Key as Bitmap) as Bitmap
For index as integer =0 To (Key.Width*Key.Height)-1
Dim crntX= index Mod(Key.Width)
Dim crntY=Math.Floor(index/Key.Width)
Dim oldColor= Main.GetPixel(crntX,crntY)
Main.SetPixel(crntY,crntX,Color.FromArgb(Key.GetPixel(crntX,crntY).R,oldColor.R,oldColor.G,oldColor.B))
Next
End Function


This function will have to run infinitley until the user presses stop and keep updating the output buffer. How can i make it faster? ( i need at least 30 executions per second)

Thanks


User is offlineProfile CardPM
+Quote Post

mark.bottomley

RE: Red Color Of One Image To The Alpha Value Of The Second

1 Jul, 2009 - 04:25 PM
Post #3

D.I.C Addict
****

Joined: 22 Apr, 2009
Posts: 780



Thanked: 127 times
My Contributions
You are doing too much math inside the loop. Use 2 loops as it will be much faster (I don't know whether it will make it to 30x). I'm not sure if the pictures are stored in row or column major order so experiment with exchanging the nesting of the loops - I believe the one below is the faster one. This setup only changes the value you care about - Alpha channel.

Also define the variables OUTSIDE the loop as they get recreated and destroyed for each iteration.

e.g.
CODE

Dim rowMax as Integer = Key.Height - 1
Dim colMax as Integer = Key.Width - 1

For row = 0 to rowMax
For col = 0 to colMax
Main.GetPixel(col, row).A = Key.GetPixel(col, row).R
Next
Next

User is offlineProfile CardPM
+Quote Post

abedjoud

RE: Red Color Of One Image To The Alpha Value Of The Second

2 Jul, 2009 - 01:40 PM
Post #4

New D.I.C Head
*

Joined: 11 Jun, 2009
Posts: 16



Thanked: 1 times
My Contributions
QUOTE(mark.bottomley @ 1 Jul, 2009 - 04:25 PM) *

You are doing too much math inside the loop. Use 2 loops as it will be much faster (I don't know whether it will make it to 30x). I'm not sure if the pictures are stored in row or column major order so experiment with exchanging the nesting of the loops - I believe the one below is the faster one. This setup only changes the value you care about - Alpha channel.

Also define the variables OUTSIDE the loop as they get recreated and destroyed for each iteration.

e.g.
CODE

Dim rowMax as Integer = Key.Height - 1
Dim colMax as Integer = Key.Width - 1

For row = 0 to rowMax
For col = 0 to colMax
Main.GetPixel(col, row).A = Key.GetPixel(col, row).R
Next
Next




Thanks for your reply mark.

Actually this function was only a small part of the code. which i managed to override all in all. However, I found out that what is really causing my code to go slow is the WriteByte. i am trying to write to an unmanaged Array in the memory (i only have its IntPtr) and it is an array of bytes. so i am using:
CODE

for index as integer = 0 to byteCount-1 'byteCount is ByteArray.length
Marshal.WriteByte(ArrayPtr,index,ByteArray(index))
next


this code is taking alot of time. it is awfully slow. Any alternative to do the same thing?
User is offlineProfile CardPM
+Quote Post

mark.bottomley

RE: Red Color Of One Image To The Alpha Value Of The Second

2 Jul, 2009 - 05:11 PM
Post #5

D.I.C Addict
****

Joined: 22 Apr, 2009
Posts: 780



Thanked: 127 times
My Contributions
I'm not sure, but I believe that the marshalling/unmarshalling to access the unmanaged memory is slow as it has to exit/enter the managed environment. What you are looking for is some sort of array copy between marshalled/unmarshalled. Try Marshal.Copy as it will only enter/exit once and likely use a machine optimal copy under the covers. that will be the fastest you will get.
User is offlineProfile CardPM
+Quote Post

abedjoud

RE: Red Color Of One Image To The Alpha Value Of The Second

2 Jul, 2009 - 08:17 PM
Post #6

New D.I.C Head
*

Joined: 11 Jun, 2009
Posts: 16



Thanked: 1 times
My Contributions
QUOTE(mark.bottomley @ 2 Jul, 2009 - 05:11 PM) *

I'm not sure, but I believe that the marshalling/unmarshalling to access the unmanaged memory is slow as it has to exit/enter the managed environment. What you are looking for is some sort of array copy between marshalled/unmarshalled. Try Marshal.Copy as it will only enter/exit once and likely use a machine optimal copy under the covers. that will be the fastest you will get.

i THINK i got it to work.

Instead of having to copy the whole image all the time. (a 32 bit <4 byte> image of 720x576pixels meaning the loop to WriteBytes() is running: 720*576*4 =1,650,880 times infinitley! and this is causing the slow link. i changed the code so that instead of writing ALL the bytes in EVERY loop, it only writes the changed bytes and leaves the other (we total @ around 3000 changed bytes every second unless we're morphing through pictures)
thats how i fixed it.
User is offlineProfile CardPM
+Quote Post

Fast ReplyReply to this topicStart new topic

Time is now: 11/7/09 10:34PM

Live VB.NET Help!

Be Social

Dream.In.Code RSS Feed Dream.In.Code LinkedIn Group Follow Us On Twitter Fan Us On Facebook

VB.NET Tutorials

Reference Sheets

VB.NET Snippets

DIC Chatroom

Bye Bye Ads

Monthly Drawing

Thumb Drive

Top Contributors

Top 10 Kudos This Month