[Okta Webinar] Learn how to a build a cloud-first strategyRegister Now

x
?
Solved

PictureBox loadpicture() array or collection urgent??

Posted on 2005-05-02
42
Medium Priority
?
1,154 Views
Last Modified: 2007-12-19
Hi, I am currently populating a file that contains all *jpg or *bmp etc.. images and there path name..then I am using an array to read each line in the file with the paths and loading the images to a picture box using an array. When the image is loaded I am checking for a specific pixel color on the image if its found then i add the filename to a listbox...

My real question is ..is there a faster way to load all images to a picturebox witout using an array or is the array the best solution..I hear about collections but I have not  dealt with collections..If creating a collection is faster to use then using an array how can I create the collection to load all images that i retrive from the HD?

The array loads an image 1 by 1 then the its checks for the pixel match, then the next image is loaded for the next check etc..

Or if there is another possible solution to speed the process up? any ideas? thanks!
0
Comment
Question by:nffvrxqgrcfqvvc
  • 23
  • 13
  • 3
  • +1
42 Comments
 
LVL 76

Expert Comment

by:GrahamSkan
ID: 13909624
in general, Collections are slower than arrays, but the overhead in either case would be dwarfed by the load process.
0
 
LVL 29

Author Comment

by:nffvrxqgrcfqvvc
ID: 13909673
In that case is there anything i can do to the array to speed it up besides adding doevents?Could you give me an example of an array that would be the fastest ?
0
 
LVL 86

Expert Comment

by:Mike Tomlinson
ID: 13909736
I wouldn't say that collections are slower than arrays...it just depends on HOW you access it.

Accessing a collection by INDEX would be slower than an accessing an array...but if you are simply iterating thru the collection using a For Each statement then it should be just as fast.

If you are dealing with thousands of files then adding the filenames to a collection will certainly be faster than using Redim Preserve since a new array would have to be created and all the contents copied over each time you resize the array.

Of course, you could always read in the entire file at once and then use Split() with vbCrLF to get an array containing all the lines of your file.

~IM
0
Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

 
LVL 86

Expert Comment

by:Mike Tomlinson
ID: 13909785
egl1044,

If you don't want an array then don't use one...

Why can't you simply load each file into the picturebox as you read each line from your file.  I don't think this is going to speed up the process though as GrahamSkan has already pointed out the the bottleneck in this operation is LoadPicture().

Adding DoEvents will not make it any faster.  In fact, it will make it slower!  DoEvents will cause your app to check and process any messages in its queue.  This will keep the app responsive while it processes the images.  For exampe, you would be able to move the form, minimize, etc. and it will property repaint itself if another form obscures it.  Without DoEvents the process will go faster but you will have an unresponsive form until the operation is complete.
0
 
LVL 29

Author Comment

by:nffvrxqgrcfqvvc
ID: 13909903
Idle Mind , thats what I am doing..I populated the list of pictures into a file then I use an array to read each line and load the images 1 by 1..
0
 
LVL 29

Author Comment

by:nffvrxqgrcfqvvc
ID: 13910096
Dim FileName As String
  FileName = App.path & "\" & "checkimages.egl"

Dim sText As String
Dim aColours As Variant
  Open FileName For Input As #1
  sText = Input(LOF(1), #1)
  Close #1
  aColours = Split(sText, vbNewLine)

Dim lIndex As Long
Dim aCount() As Long
Dim lColourCount As Long
  lColourCount = UBound(aColours)
  On Error Resume Next
  ReDim aCount(lColourCount) As Long
  For lIndex = 0 To lColourCount
aColours(lIndex) = (aColours(lIndex))
Picture1.Picture = LoadPicture(aColours(lIndex))
Picture1.PaintPicture Picture1.Picture, 0, 0, Picture1.ScaleWidth, Picture1.ScaleHeight
 aCount(lIndex) = 0
Next lIndex

'This is how I am currently loading the images? I am just wondering if there is a faster solution, I understand that loadpicture is the cause of most of the problem and not the array but if this array could be edited to be faster? if not then is there anything that I can do to the image as its loading the picture...for example does it take the same amount of time to load the entire image without resizing it using paintpicture and it would if i did resize it or would it be faster? Or possibly anything else I can do to the picturebox to speed things up? Just curious?
0
 
LVL 86

Expert Comment

by:Mike Tomlinson
ID: 13910415
Using NATIVE VB I don't think you can get it going any faster.  I imagine it would probably run faster if you loaded/manipulated the image completely via APIs but I don't have any examples for you...
0
 
LVL 76

Expert Comment

by:GrahamSkan
ID: 13910560
If you understand the image formats - & I don't, except for the Exif (metadata) information in JPEGs - you could open the files in binary mode and search through them for the pixel information that you require. That would make the program run faster, but I suspect that it would stretch the development time beyond acceptability.
0
 
LVL 29

Author Comment

by:nffvrxqgrcfqvvc
ID: 13910562
OK..I think I know the problem but am not sure if this would matter or not

ok when I create the list of paths and filenames to the image when theres long filenames it uses 2 lines instead of one..i dunno if wordpad formats it like that or if the array is reading the entire line?

for example when I open the file with all my image paths...

These are all on 1 line::

c:\America Online 6.0\MyCalendar\Help\month_button2.gif 'first line
c:\America Online 6.0\MyCalendar\Help\print_button.gif 'second line
c:\America Online 6.0\MyCalendar\Help\repeats_button.gif 'third line

BUT in some cases if theres a long pathname it shows up in wordpad as this::

c:\Documents and Settings\Administrator\Desktop\files\Photo42\
Photo39.jpg
c:\Documents and Settings\Administrator\Desktop\files\Photo42\
Photo40.jpg
c:\Documents and Settings\Administrator\Desktop\files\Photo42\
Photo41.jpg

'Does the array pick up on this or is this just how wordpad formats it? when the array reads those long pathname lines is it reading it as 1 line because wordpad is showing it as 2 lines when it should be 1 line only?
0
 
LVL 29

Author Comment

by:nffvrxqgrcfqvvc
ID: 13910589
because the array is so fast that it freezes when loading the images...in this sense should what would be the best wait to pause the loading of the pictures..

sleep 100
doevents

or API

TimerQueue etc..
0
 
LVL 76

Expert Comment

by:GrahamSkan
ID: 13911238
egl1044,
 I don't know what resolution your monitor can display, or what the font size you are using to display the list in WordPad, but I am sure that the difference is just a matter of text formatting and is not revelant to your problem.

You seem to be introducing a new problem of 'freezing'. If this is happening, it is unlikely to be caused by the array speed being too fast. It is the nature of most programs, and it is especially true of VB, that they will wait until the previous request (statement or function) has been completed before the program resumes with the next instruction. DoEvents will probably have no noticeable  deleterious effect on the program.
0
 
LVL 29

Author Comment

by:nffvrxqgrcfqvvc
ID: 13911510
Never mind...thanks for the advice.
0
 
LVL 29

Author Comment

by:nffvrxqgrcfqvvc
ID: 13911526
It only seems to freeze when I am scanning the entire HD of C:\

If i scan directories it works perfect

And the formating is correct in notepad so dish my other question!
0
 
LVL 7

Expert Comment

by:OHDev2004
ID: 13915569
Just a Question:
what's the Following Line for:
Picture1.PaintPicture Picture1.Picture, 0, 0, Picture1.ScaleWidth, Picture1.ScaleHeight

since you Load the Picture with   Picture1.Picture = LoadPicture(aColours(lIndex))


I Suggest you remove that PainPicture1 Line because it's Increasing ur Processing Time Twice I think !


why do you use that Line to Paint the Picture when it's already there ???
another thing inplace of using the Picture1.Point(X,Y) to get the Pixel Color I suggest you use the GetPixel API which is faster
'Declaration:
Public Declare Function GetPixel Lib "gdi32" Alias "GetPixel" (ByVal hdc As Long, ByVal x As Long, ByVal y As Long) As Long

Usage:
Dim PixelColor as Long
PixelColor = GetPixel(Picture1.HDC,X,Y)

Please let me know if you have any Questions :)
OHDev


0
 
LVL 29

Author Comment

by:nffvrxqgrcfqvvc
ID: 13918775
I use paintpicture to resize the image to the picturebox size on the form. All the images are of various sizes so I use paintpicture to resize the image because I am getting the pixel color from the middle portion of the picture itself, if I didn't use paintpicture then the color of the pixel in the middle portion of the picture wouldnt be correct.

0
 
LVL 29

Author Comment

by:nffvrxqgrcfqvvc
ID: 13918819
I am not using getpixel api because I am using twips scalemode, also I am converting the color of the middle point on the picturebox to a hex value.
0
 
LVL 7

Expert Comment

by:OHDev2004
ID: 13918826
Ok ... since this will Increase the speed of the whole Process if you don't use the Paintpicture thing ...

why not Calculate the Middle of the Picture and get that Pixel without resizing ...

Because at least if you resize the Picture it won't be 100% right ... I mean some of the Pixels get Corrupted or in other words change in color in order for the Image to resize.

so My Opinion is to calculate the Location of that Pixel and get it inplace of Resizing the Picture
OHDev
0
 
LVL 7

Accepted Solution

by:
OHDev2004 earned 2000 total points
ID: 13918924
Dim MiddleX as Integer,MiddleY as Integer
Dim PixelColor as Long
MiddleX = Int(Picture1.ScaleX(Picture1.ScaleWidth, vbTwips, vbPixels))
MiddleY = Int(Picture1.ScaleY(Picture1.ScaleHeight, vbTwips, vbPixels))

PixelColor = Hex(GetPixel(Picture1.Hdc,MiddleX,MiddleY))

this does the Trick ... it get's the Middle Pixel Color and converts it to HEX
I had to convert to Pixel Scale to use the GetPixel API ... but I only used that in the Variable as you see ,,, so you don't have to change the scalemode of the Picturebox

OHDev
0
 
LVL 29

Author Comment

by:nffvrxqgrcfqvvc
ID: 13919540
I get an error on the following line:

PixelColor = Hex(GetPixel(Picture1.hdc, MiddleX, MiddleY))
0
 
LVL 29

Author Comment

by:nffvrxqgrcfqvvc
ID: 13919586
okay the error is that MiddleX and MiddleY have to be used as a Val and not Int

I  changed Int to Val and it works
0
 
LVL 29

Author Comment

by:nffvrxqgrcfqvvc
ID: 13919607
Nope. Actually it worked for 1 image but now its not working when I tried another image? any ideas why?? I will use this, its much better then .point method.? any ideas why I am getting type mismatch error?
0
 
LVL 29

Author Comment

by:nffvrxqgrcfqvvc
ID: 13919630
Okay I had to change PixelColor Variable to a string rather than using a Long variable...
0
 
LVL 7

Expert Comment

by:OHDev2004
ID: 13919733
I'm Glad this Worked with you

Sorry I forgot to mention to Divide the values to get the Middle ...

MiddleX = Int(Picture1.ScaleX(Picture1.ScaleWidth, vbTwips, vbPixels) / 2)
MiddleY = Int(Picture1.ScaleY(Picture1.ScaleHeight, vbTwips, vbPixels) / 2)
PixelColor = Hex$(GetPixel(Picture1.hdc, MiddleX, MiddleY))

and above I fixed the Type Mismatch error
thank you
OHDev
0
 
LVL 7

Expert Comment

by:OHDev2004
ID: 13919743
oh and remember change PixelColor back to Long if you want
0
 
LVL 29

Author Comment

by:nffvrxqgrcfqvvc
ID: 13919838
It works good, It even stoped my application from freezing when I compile it...It used to freeze when I would scan the entire HD but now it doesnt even freeze. Thanks for the advice you solved the major issue. Appreciate it.
0
 
LVL 7

Expert Comment

by:OHDev2004
ID: 13919871
Youre More than welcome
Thank you
OHDev
0
 
LVL 29

Author Comment

by:nffvrxqgrcfqvvc
ID: 13919881
Since this question is PAQ'ed I just want to ask if you know of any website that will show me HTML hex code for skin colors...maybe a list I searched and found some but not very good.

Im converting web hex to vb hex and comparing them but haven found a good list of HTML hex skin colors..I searched for an adobe color hex codes for skin tones but didn't have an luck thought they might be the best.
0
 
LVL 7

Expert Comment

by:OHDev2004
ID: 13919904
I'm not sure of what  Skin colors are ...
if you mean the Web Safe Palette I can search for that ?
OHDev
0
 
LVL 29

Author Comment

by:nffvrxqgrcfqvvc
ID: 13919937
Skine tone colors..as in possible pigment colors

which would be similar to pinkish to brownish..etc
some are listed below.. HTML hex.

FFDCB1
E5C298
E4B98E
E2B98F
E3A173
D99164
CC8443
C77A58
A53900
880400
710200
440000
FFE0C4
EECFB4
DEAB7F
E0B184
0
 
LVL 29

Author Comment

by:nffvrxqgrcfqvvc
ID: 13919947
Just though maybe adobe photoshop would have a list of hex values associated with skin tone colors but I searched with no luck...
0
 
LVL 7

Expert Comment

by:OHDev2004
ID: 13920018
I Didn't find any neither ...


But I have a very neat Idea :P
Before this Idea check the following Image
http://www.ackadia.com/html/images/websafe_palette-deutan.jpg


bring a Websafe Color Palette  you can find many on the Web ... here is one:
http://www.creationguide.com/palettes/palette216.gif

Download it and open it in Photoshop ...
then Click the ImageMenu then Mode > RGB Color

then Click the "Layer" Menu then New Fill Layer>Solid Color
then choose a Browny Color...

then set the Mode of that new Overlay Layer From Normal to Color or Hue
and you should have a Pallete made of Browny Like colors :P

Just a Crazy Idea but it may help :P
OHDev
0
 
LVL 29

Author Comment

by:nffvrxqgrcfqvvc
ID: 13920114
Thats a good idea im going to have to find a trial version of adobe. I don't have the software.
0
 
LVL 7

Expert Comment

by:OHDev2004
ID: 13920253
Ok I made this for you on the Fly :P
http://www40.brinkster.com/OHDev/skinny.html

OHDev
0
 
LVL 29

Author Comment

by:nffvrxqgrcfqvvc
ID: 13920632
The left pallete looks perfect but is there anyway I can get the HTML hex of each block of pallete?
0
 
LVL 29

Author Comment

by:nffvrxqgrcfqvvc
ID: 13920664
I suppose I can load the image in VB and move the cursor over each block and use getpixel?

and have it format it to a websafe color...or is there a option in photoshop because i download the trial..

'Here is the code to make a hex color to a websafe color

Public Function CvtColorWeb2VB(colorcode As String) As _
    String
    'Convert HTML hexedecimal color to VB Hexedecimal
    If Len(colorcode) < 6 Then
       colorcode = colorcode & String(6 - Len(colorcode), _
           "0")
    End If
    CvtColorWeb2VB = "&H" & Mid(colorcode, 5, 2) & _
        Mid(colorcode, 3, 2) & Mid(colorcode, 1, 2)
End Function

0
 
LVL 7

Expert Comment

by:OHDev2004
ID: 13920666
hmm :P

you can write a Little VB Program to do that and to store them in a Text file ...
Let me know if you want any help with it ...
(The Idea is to Loop through the Image by blocks)

OHDev
0
 
LVL 29

Author Comment

by:nffvrxqgrcfqvvc
ID: 13920669
oops thats websafe hex color to vb hex
0
 
LVL 29

Author Comment

by:nffvrxqgrcfqvvc
ID: 13920711
K i got it to work

0
 
LVL 7

Expert Comment

by:OHDev2004
ID: 13920725
lol ... I think you should write a Little Function to Loop through the Image
Row By Row

like defining a BlockX,BlockY
BlockX=10
BlockY=10

Dim Xloop as Integer,Yloop as Integer

Open "C:\Skinny.Txt" for Output as #1

For Xloop = 0 To Int(Picture1.ScaleX(Picture1.ScaleWidth, vbTwips, vbPixels)) Step BlockX
 For YLoop = 0 To  Int(Picture1.ScaleY(Picture1.ScaleHeight, vbTwips, vbPixels)) Step BlockY
  Write #1, GetPixel(Picture1.HDC,Xloop,Yloop)
 Next Yloop
Loop Xloop

I just wrote that here ... so you may need to modify things ...
OHDev
0
 
LVL 29

Author Comment

by:nffvrxqgrcfqvvc
ID: 13920758
haha, well I did the mouse click thing..i clicked on each block and got the VB hex value...alot of mouse clicks haha..

284A
3063
84173
386B
8497B
18598C
29619C
31699C
4279AD
528EBD
6BA6D6
73B6E7
A5D7FF
8497B
386B
31699C
2852
215994
5296C6
104984
4173
104984
3971A5
4286B5
7BB6EF
185184
305A
296194
5A96C6
8417B
3979AD
21598C
386B
3863
185184
3171A5
10497B
29699C
4A86BD
6BAEDE
216194
4279AD
639ECE
84BEEF
4279B5
5A96CE
31699C
528EBD
8CCFFF
105184
8CC7F7
4A86B5
216194
216194
4A86B5
73AEDE
8417B
4279AD
6BA6D6
84BEEF
31699C
3171A5
7BB6EF
63A6D6
29699C
4173
73AEE7
5A96CE
8CCFFF
B5DFFF
528EC6
4A86B5
73B6E7
73AEDE
84173
639ED6
94CFFF
3979AD
7BBEEF
A5D7FF
6BA6D6
3971AD
185184
63A6D6
21598C
5A96C6
305A
4A8EBD
8CC7F7
4279AD
5A9ECE
8CCFFF
2852
31699C
B5DFFF
18598C
5A9ECE
73AEDE
7BB6E7
3171A5
8CC7F7
29619C
C6E7FF
BDE7FF
7BB6EF
528EBD
DEEFFF
639ECE
21598C
284A
528EBD
6BA6D6
84BEEF
73B6E7
84BEEF
528EBD
6BA6D6
639ECE
7BBEEF
3171A5
94CFFF
3971AD
4A86B5
18598C
528EBD
7BB6E7
6BAEDE
CEEFFF
6BA6D6
D6EFFF
9CD7FF
4279B5
84C7F7
ADDFFF
639ECE
5A96C6
215994
10497B
296194
5296C6
4286B5
63A6D6
84173
3971A5
9CD7FF
73B6E7
305A
8CC7F7
3971A5
4A86B5
63A6D6
185184
296194
94CFFF
84BEEF
73AEDE
185184
5296C6
5A96C6
3171A5
4A8EBD
4A8EBD
5A9ECE

0
 
LVL 7

Expert Comment

by:OHDev2004
ID: 13920769
Private Sub Picture1_MouseUp(Button As Integer, Shift As Integer, X As Single, Y As Single)
 List1.AddItem Hex$(GetPixel(Picture1.hDC, Picture1.ScaleX(X, vbTwips, vbPixels), Picture1.ScaleX(Y, vbTwips, vbPixels)))
End Sub

OHDev
0
 
LVL 7

Expert Comment

by:OHDev2004
ID: 13920776
OOPS :P :D:D:D

you were faster than me :)
OHDev
0

Featured Post

How to Use the Help Bell

Need to boost the visibility of your question for solutions? Use the Experts Exchange Help Bell to confirm priority levels and contact subject-matter experts for question attention.  Check out this how-to article for more information.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Article by: Martin
Here are a few simple, working, games that you can use as-is or as the basis for your own games. Tic-Tac-Toe This is one of the simplest of all games.   The game allows for a choice of who goes first and keeps track of the number of wins for…
Background What I'm presenting in this article is the result of 2 conditions in my work area: We have a SQL Server production environment but no development or test environment; andWe have an MS Access front end using tables in SQL Server but we a…
As developers, we are not limited to the functions provided by the VBA language. In addition, we can call the functions that are part of the Windows operating system. These functions are part of the Windows API (Application Programming Interface). U…
Show developers how to use a criteria form to limit the data that appears on an Access report. It is a common requirement that users can specify the criteria for a report at runtime. The easiest way to accomplish this is using a criteria form that a…
Suggested Courses

834 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question