How can I find out what size a JPG picture has without opening it up in a Image controll or Picture controll. The picture is saved in Adobe Photo Shop 6.X. If I save it in a PSP or something I can do something like this to find the size.
VB Code:
Public Type ThePicInfo
Type As String
Width As Long
Height As Long
End Type
Private Function CheckPicSpecs(TheFile) As ThePicInfo
Dim TheContent, TheImageInfo As ThePicInfo, TheVar, TheFreeFile
as I told you in the other forum where you posted this exact same question, the fact that it was created from or with Adobe is irrelevant. What is relevant is the JPG file format and you can find that at any number of sites on the web that give file formats. There is a pointer to one such at the link below my name.
So can you then tell me why the function that I posted in my first post is working if I am saving it in PSP, but is not working if I am saving it in Adobe Photo Shop... .... It gives me something like 5079 in width and 10497 in height no matter what size it is if I am saving it in Adobe, and the right size if I am saving it in PSP....
Look at this example. They are using the same function to read the size of the picture. But are reading the information from two diffrent files. One is saved in PSP, and the other one in Adobe Photo Shop. What is wrong???
I'm not sure what your question is but it appears that you think JPG files created by different applications have different structure, but they don't. They might have different resolution and different size, but they have the same file structure, so no matter what application created the JPG file, the PLACE in the JPG file that has the bytes containing the picture size will be the same even if the CONTENTS are different.
I"m not really sure if I have answered your question because I'm not really sure just what your question is.
A JPEG File does NOT have a set structure that can be retrieved from the same position in the file every time. They have the same information, but it's not always in the same position. If you want, visit www.wotsit.org to look up JPG specs, but I've done that before myself, and here's how you retrieve it.
-Get ALL data from the file
-Search for an occurrence of chr$(255)+chr$(192) (refer to as x from here on out)
-Image height is a flip-flopped word (unsigned integer) in positions x+5 and x+6
-Image width is a flip-flopped word in positions x+7 and x+8
I'm not sure how to mimic the MAKWRD statement in VB, but I'm also not at my development machine, however, making a 2 byte string and using the CVI function may work, or LSETting a TYPEd variable equal to that 2 byte string.
Hope this helps, If you still have problems with this by next week, I will try to port this over to VB when I get back to my dev machine next weekend.
phinds: I am not sure if you saw my example. But if you teste4d it you would see that my function is working on files saved in PSP. So stop telling me that it has nothing to say what app I am saving my JPGs in. But I think that BigDrake here is closer to a solution. He says that the height and width is not stored the same time always. But in PSP they do it anyway, but probably not in Adobe Photo Shop (This is so much easier with BMP.. )...
OK BigDrake, I have never seen PowerBasic before but I am trying to write your code in VB. But I have some questions...(you should try to comment you code a bit..)...
Q1: You say that it is stored in an unsigned Integer. But I am not 100% what a unsigned Integer is. How many Bytes is it. Or is it not static?
Q2: You say that I have to search for chr$(255)+chr$(192), is that two characters right after each other. Or is one of the characters for Width and one for Height?
Q3: I can see in your code that you are adding the "character" to a byte datatype. (tmp1=ASC(MID$(jpegdata,x+5,1)))...is byte 1 byte big in PowerBasic too?
Q4: And you are talking about that MAKWRD function. What does it actually do. If you try to explain I can probably find something equal in VB.
Thanks this is working.....YEEEEEEEES....I am going to rewrite the functions in some hours to make it look a little bit better then it does now. And I will post it. Thanks BigDrake...you have been to great help...
NOOOOOOOOOO....it is still not working. I only tested it on the PSP JPG picture, and it is working on that one, but not on the ADOBE picture. Here I have made a working sample of it. Any one???
Sorry, I'm VERY bad not to comment code sometimes.
Q1: It is an number that can't go negative so it increases the range. Tmp1 and Tmp2 are the High and Low Byte, however, I don't remember which one is which.
Q2: Yes, ASCII 255 right after ASCII 192
Q3: Yes
Q4: See code below (will have to expand a bit to include file reading)
Not sure if tmp1 should be first in the calculation or tmp2, but the MAKWRD function takes 2 8 bit values and creates a 16 bit from it. If you ever have to convert a 4 byte long to a number without VB's nice conversion functions, you can do that as follows:
Code:
dim x as long
x=(byte1*256^3)+(byte2*256^2)+(byte3*256)+byte4
The math can be done as follows (you'll probably have to experiment to make sure tmp1 and tmp2 are in the right places):
Code:
Dim tmp1 as BYTE
dim tmp2 as BYTE
dim SrchString as String
dim scrheight as LONG
dim scrwidth as long
dim x as long
SrchString=chr$(255)+Chr$(192)
x=instr(JpegData,SrchString)
tmp1=asc(mid$(JpegData,x+5,1))
tmp2=asc(mid$(JpegData,x+6,1))
ScrHeight=(tmp1*256)+tmp2
tmp1=asc(mid$(JpegData,x+7,1))
tmp2=asc(mid$(JpegData,x+8,1))
ScrWidth=(tmp1*256)+tmp2
Yes I found out all of that if you read my post....but did you see my example app???? I can't understand what is wrong. I think I have translated your example in to VB code, and it is working great for the picture saved in PSP, but not for the one saved in Adobe....I can't understand what is wrong. Any help is appreciated.
I will not be where I can download and run the app until next weekend. I'll be able to look at it then...
If you could post some of the code here, I might be able to look at it sometime this week, but I won't be able to download and run anything until next weekend...
Does XPos actually find anything in an Adobe Photoshop file? That's actually all I've ever tested on.
A recommendation...When reading the file, instead of a for...next loop to read the entire file, you can do it like this, and it might be a bit faster:
Code:
Open JpegFile$ for binary access read shared as #1 len=16384
jpegdata$=space$(lof(1))
get #1,1,jpegdata$
close #1
the len part of the binary open statement specifies a buffer.
I did notice that inside your type variable you only have a .Height member, and not a .Width, and you're using 'type' as a member name. Don't know if that's allowed, but I try to steer clear of using VB keywords as member names or variable names.
I did notice that inside your type variable you only have a .Height member, and not a .Width, and you're using 'type' as a member name. Don't know if that's allowed, but I try to steer clear of using VB keywords as member names or variable names.
Sorry, that was only a miss spelling. It was used to check if it was a GIF or a JPG in the old function. But since I am only going to use JPG, I was going to delete the type variable when I posted it here, but deleted wrong line......
Does XPos actually find anything in an Adobe Photoshop file? That's actually all I've ever tested on.
Yes it finds something down at byte 1255....
A recommendation...When reading the file, instead of a for...next loop to read the entire file, you can do it like this, and it might be a bit faster:
Thanks, but I hate using shortcuts like $ in my code. It makes it harder to read. And BTW why are you writing len=16384. The file is nopt this size all the time. Some times bigger and some times smaller. Has that something to say?
And I got an error when I tried your read function. "Excpected Array" on the Space$ variable...
the len=16384 when opened in binary only specifies a buffer for the file reading. Basically the computer only does a physical read every 16384 bytes (16k), you can use 8192, or whatever you'd like. With larger files it tends to speed up the reading. In VB6 at least, the SPACE$() function returns the number of spaces specified. It is a VB function. It might be just Space() in other versions, not sure.
The $ was only used to be sure you knew what variable type I was using...
I'm about to head out on a 10 hour drive, and more than likely will not have internet where I am, so I may not be much help over the next few days. If you don't resolve the issue by next weekend, I'll try my best to help out, may get you to email me the file you have or something like that.
I am not sure what was wrong, but I commented out Option Explicit and your function worked........But speed is not a problem with my app at all. It is making more then 100 html pages in 2/10 of a sec.
I will try to figgure it out before you are comming back. But it would be great if you could take a look at it if I don't before the week is over. Thanks.
I know have one more clue here. If I save the picture in Adobe using the Save As function. My VB function is not working. But if I am saving it using the "Save for web" function, my VB function are working. I am getting so confussed here...
I think that this might be where I have failed with your code BigDrake. But I ain't good with Perl and the link wan't work. So I am still looking for a solution.
The header of a JPEG file consists of a series of blocks, called "markers".
The image height and width are stored in a marker of type SOFn (Start Of
Frame, type N). To find the SOFn you must skip over the preceding markers;
you don't have to know what's in the other types of markers, just use their
length words to skip over them. The minimum logic needed is perhaps a page
of C code. (Some people have recommended just searching for the byte pair
representing SOFn, without paying attention to the marker block structure.
This is unsafe because a prior marker might contain the SOFn pattern, either
by chance or because it contains a JPEG-compressed thumbnail image. If you
don't follow the marker structure you will retrieve the thumbnail's size
instead of the main image size.) A profusely commented example in C can be
found in rdjpgcom.c in the IJG distribution (see part 2, item 15). Perl
code can be found in wwwis, from http://www.tardis.ed.ac.uk/~ark/wwwis/.
Hurra!!!!!!!!!!!!!!!!! YEEEEEEEEEEEES I made it work. This is the function. It is a lot more addvanced. And can be used with a lot more of the JPG files out there. And don't have pit falls like the two other functions....
VB Code:
Private Type BITMAPINFO
Width As Long
Height As Long
End Type
Private Function GetJPGInfo(ByVal FileName As String) As BITMAPINFO