|
Post by alexfish on Dec 23, 2018 20:33:07 GMT 1
Hi All
Whilst working on the toolkit for the RPI (Raspberry PI) RE a WebKit(Browser)
I need a quick method of getting the size of image and found that PHP has a module to do so + it will get the size of image from a remote site
Example usage
./getimagesize /path/to/local/image ./getimagesize http://www.basic-converter.org/qix.jpg
BR Alex
the code assuming php is on the system
SUB GetImageSize( STRING pathto$, int * w,int *h)
LOCAL begin$ ,result$ TYPE STRING begin$=begin$ & "php -r '$x=" & CHR$(34) & "x" & CHR$(34) & ";$size=getimagesize(" & CHR$(34) begin$=begin$ & pathto$ & CHR$(34) & ");" & "$width = $size[0];$height = $size[1];print $width." &CHR$(34) begin$=begin$ & "x" & CHR$(34) & ".$height;'" result$= EXEC$(begin$) *w= VAL( MID$(result$,1,INSTR(result$,"x")-1)) *h= VAL(MID$(result$,INSTR(result$,"x")+1))
END SUB
LOCAL w,h TYPE int LOCAL arg$ TYPE STRING IF (argc >=2) THEN arg$=argv[1] GetImageSize(arg$,&w,&h) PRINT "Image Size " , w, ":" , h ELSE PRINT "usage\n execfile '/path/to/image'" END IF
|
|
|
Post by alexfish on Dec 23, 2018 21:06:24 GMT 1
Updated code above
Got Rid of the DEF FN (...)
BR Alex
|
|
|
Post by rikky on Dec 24, 2018 16:54:31 GMT 1
You can do this in real BaCon, I'm sure. Only, I can not do this, yet. Getting only the header from a normal html page is something like this: OPEN "www.basic-converter.org:80" FOR NETWORK AS mynet SEND "GET / HTTP/1.1\r\nHost: www.basic-converter.org\r\n\r\n" TO mynet
RECEIVE header$ FROM mynet PRINT header$
CLOSE NETWORK mynet You get : HTTP/1.1 200 OK Server: nginx Date: Mon, 24 Dec 2018 15:45:13 GMT Content-Type: text/html Content-Length: 44441 Connection: keep-alive Last-Modified: Sat, 22 Dec 2018 12:41:23 GMT ETag: "ad99-57d9bae7613cc" Accept-Ranges: bytes
<!DOCTYPE html> <html lang="en"> <head> <meta HTTP-EQUIV="CACHE-CONTROL" CONTENT="NO-CACHE"> <meta HTTP-EQUIV="EXPIRES" CONTENT="0"> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="description"
HTTP/1.1 200 OK Server: nginx Date: Mon, 24 Dec 2018 15:45:13 GMT Content-Type: text/html Content-Length: 44441 Connection: keep-alive Last-Modified: Sat, 22 Dec 2018 12:41:23 GMT ETag: "ad99-57d9bae7613cc" Accept-Ranges: bytes
<!DOCTYPE html> <html lang="en"> <head> <meta HTTP-EQUIV="CACHE-CONTROL" CONTENT="NO-CACHE"> <meta HTTP-EQUIV="EXPIRES" CONTENT="0"> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="description"
It contains also the content-length of the html page. But If I fill in www.basic-converter.org/qix.jpg, then I get: HTTP/1.1 400 Bad Request Server: nginx Date: Mon, 24 Dec 2018 16:07:35 GMT Content-Type: text/html Content-Length: 166 Connection: close
<html> <head><title>400 Bad Request</title></head> <body bgcolor="white"> <center><h1>400 Bad Request</h1></center> <hr><center>nginx</center> </body> </html>
So, all there is to do, is invent an other SEND string$ TO mynet. Rik.
|
|
|
Post by alexfish on Dec 24, 2018 19:35:20 GMT 1
Hi Rik
will shortly be posting on the RPI a demo using lib curl & php m+ gumbo parser. this module is part of my own webkit, it has taken 1 month to figure out gumbo + 3 months to get this module working
if can succeed in getting the sizes & images & plus in 'youtube' & this 'forum' then will be looking good
BR Alex
|
|
|
Post by alexfish on Dec 24, 2018 20:56:31 GMT 1
Hi Rik
as far as i can tell the image data is at front of header info
if do a test using curl header request then it will spew out the image data first and then the header, the header does not contain the width or height on bacon.org. a while a go Vovchik and I did some work on getting image data by converting char data {bytes}.
in php there is a function to get x bytes of data.
can BaCon do this
if so then maybe can take a look at the appropriate thread again
BR Alex
|
|
|
Post by rikky on Dec 25, 2018 9:09:13 GMT 1
Oke, getting only the real header of the jpg is: OPEN "www.basic-converter.org:80" FOR NETWORK AS mynet SEND "HEAD /qix.jpg HTTP/1.1\r\nHost: www.basic-converter.org\r\n\r\n" TO mynet
RECEIVE header$ FROM mynet PRINT header$
CLOSE NETWORK mynet
You get: HTTP/1.1 200 OK Server: nginx Date: Tue, 25 Dec 2018 08:00:30 GMT Content-Type: image/jpeg Content-Length: 22957 Connection: keep-alive Last-Modified: Tue, 16 Apr 2013 06:55:57 GMT ETag: "59ad-4da74dc7bb940" Accept-Ranges: bytes
Content-Length: 22957 Which is NOT exactly what you want, but it already tells you, if the image is big or small. I can assure you, that there is not an extra field in the header, that is specially and only for php to read. So php has not more information than we have, at this moment. There must be one more trick. Maybe the header of the image contains this information? merry Xmas. Rik.
|
|
|
Post by bigbass on Dec 25, 2018 19:26:58 GMT 1
hello Alex
for just the size for a remote file you could use exiv2
exiv2 http://www.basic-converter.org/qix.jpg | grep "Image size"
Result
95kb its small and I tested this on the RPI3 before posting
sudo apt-get install exiv2
a lot of command line options but a pipe to grep was easier for a quick answer because on some files you may get "No Exif data found in the file" but at least you get the size this way
Joe
|
|
|
Post by alexfish on Dec 26, 2018 11:22:00 GMT 1
Hi Joe that's for that one yet after some further searches managed to find a c++ example that does not require <arpa/inet.h> to sort the endians, this example use the bit shift and think will be easy to convert to BaCon further scoring have a list of how to get the headers/meta data , but need to look at them in detail will not be able to post this until next week however think if someone can manage to get bacon to get x bytes from the http rather than curl , that would be cool,, hint hint BR Alex the example//http://www.cplusplus.com/forum/beginner/45217/
#include <iostream> #include <fstream>
using namespace std;
bool GetImageSize(const char *fn, int *x,int *y) { FILE *f=fopen(fn,"rb"); if (f==0) return false; fseek(f,0,SEEK_END); long len=ftell(f); fseek(f,0,SEEK_SET); if (len<24) { fclose(f); return false; } cout << fn << endl; // Strategy: // reading GIF dimensions requires the first 10 bytes of the file // reading PNG dimensions requires the first 24 bytes of the file // reading JPEG dimensions requires scanning through jpeg chunks // In all formats, the file is at least 24 bytes big, so we'll read that always unsigned char buf[24]; fread(buf,1,24,f);
// For JPEGs, we need to read the first 12 bytes of each chunk. // We'll read those 12 bytes at buf+2...buf+14, i.e. overwriting the existing buf. if (buf[0]==0xFF && buf[1]==0xD8 && buf[2]==0xFF && buf[3]==0xE0 && buf[6]=='J' && buf[7]=='F' && buf[8]=='I' && buf[9]=='F') { long pos=2; while (buf[2]==0xFF) { if (buf[3]==0xC0 || buf[3]==0xC1 || buf[3]==0xC2 || buf[3]==0xC3 || buf[3]==0xC9 || buf[3]==0xCA || buf[3]==0xCB) break; pos += 2+(buf[4]<<8)+buf[5]; if (pos+12>len) break; fseek(f,pos,SEEK_SET); fread(buf+2,1,12,f); } }
fclose(f);
// JPEG: (first two bytes of buf are first two bytes of the jpeg file; rest of buf is the DCT frame if (buf[0]==0xFF && buf[1]==0xD8 && buf[2]==0xFF) { *y = (buf[7]<<8) + buf[8]; *x = (buf[9]<<8) + buf[10]; //cout << *x << endl; return true; }
// GIF: first three bytes say "GIF", next three give version number. Then dimensions if (buf[0]=='G' && buf[1]=='I' && buf[2]=='F') { *x = buf[6] + (buf[7]<<8); *y = buf[8] + (buf[9]<<8); return true; }
// PNG: the first frame is by definition an IHDR frame, which gives dimensions if ( buf[0]==0x89 && buf[1]=='P' && buf[2]=='N' && buf[3]=='G' && buf[4]==0x0D && buf[5]==0x0A && buf[6]==0x1A && buf[7]==0x0A && buf[12]=='I' && buf[13]=='H' && buf[14]=='D' && buf[15]=='R') { *x = (buf[16]<<24) + (buf[17]<<16) + (buf[18]<<8) + (buf[19]<<0); *y = (buf[20]<<24) + (buf[21]<<16) + (buf[22]<<8) + (buf[23]<<0); return true; }
return false; }
int main() {
const char *theFile = "BaConEyes.png"; int the_x =0; int the_y =0; bool didRun = false;
didRun = GetImageSize(theFile, &the_x, &the_y);
cout << "Dimensions: " << the_x << " x " << the_y << endl; return 0; }
|
|
|
Post by alexfish on Dec 26, 2018 11:34:54 GMT 1
Hi all had a quick look at Peters HTTP thread think this bit could do the trick basic-converter.proboards.com/thread/1030/fetching-https?page=1' Send the GET request to the remote server SSL_write(ssl, req$, LEN(req$)) REPEAT ' Fetch the response into the buffer IF SSL_read(ssl, buf$, BufferSize) < 0 THEN CONTINUE total$ = total$ & buf$ << can try shutdown here after x Bytes memset((void*)mem, 0, BufferSize) UNTIL ISFALSE(WAIT(mynet, 500)) BR Alex
|
|
|
Post by rikky on Dec 26, 2018 20:54:53 GMT 1
With the information above I figured that the Y coordinate is on offset 7 and 8, and the X is on 9 and 10. I supose <<8 means multiplying by 256, but I don't speak c++. OPEN "www.basic-converter.org:80" FOR NETWORK AS mynet
SEND "HEAD /qix.jpg HTTP/1.1\r\nHost: www.basic-converter.org\r\n\r\n" TO mynet RECEIVE header$ FROM mynet
start$ = "" slip_counter = 0 char_counter = 0
WHILE 0=0
SEND "GET /qix.jpg HTTP/1.1\r\nHost: www.basic-converter.org\r\n\r\n" TO mynet RECEIVE body$ FROM mynet
'sometimes it recieves a "", but there is more to come. IF body$ = "" THEN 'PRINT NL$ & "slip" & NL$ INCR slip_counter IF slip_counter = 6 THEN BREAK CONTINUE END IF slip_counter = 0 'we received something FOR i = 1 TO LEN(body$) IF HEX$(ASC(MID$(body$,i+1,1))) = "FF" AND \ HEX$(ASC(MID$(body$,i+2,1))) = "D8" AND \ HEX$(ASC(MID$(body$,i+3,1))) = "FF" AND \ HEX$(ASC(MID$(body$,i+4,1))) = "E0" THEN start$ = "yes" PRINT "Found jpg:" 'this means we start at offset 1 for char_counter 'one more then in the example
END IF IF start$ = "yes" THEN INCR char_counter END IF IF char_counter = 8 THEN y1$ = STR$(ASC(MID$(body$,i,1))) END IF IF char_counter = 9 THEN y2$ = STR$(ASC(MID$(body$,i,1))) 'somehow y1 is a variable that is forbidden. yy1 = VAL(y1$) * 256 yy2 = VAL(y2$) Y = yy1 + yy2 PRINT "Y : " & STR$(Y) END IF IF char_counter = 10 THEN x1$ = STR$(ASC(MID$(body$,i,1))) END IF IF char_counter = 11 THEN x2$ = STR$(ASC(MID$(body$,i,1))) xx1 = VAL(x1$) * 256 xx2 = VAL(x2$) X = xx1 + xx2 PRINT "X : " & STR$(X) END END IF NEXT i WEND
CLOSE NETWORK mynet
Gives Y : 8444 and X : 35307 Obviously this is not 426 x 347, which means I am mistaken. Either the offset of the bytes, or I do not know what <<8 means. Rik.
|
|
|
Post by Pjot on Dec 27, 2018 9:20:21 GMT 1
Hi Rik, I am not an expert in JPEG images, but maybe the following suggestions may help you: - Note that binary downloads need to be handled in a different way compared to textual downloads. On the BaCon website you will find an example on how to handle downloading a binary file.
- Looking at your markers 'FF' 'D8' 'FF' 'E0', they seem to identify the JFIF type. But the actual JPEG format uses different markers: 'FF' 'D8' 'FF' 'C0'.
HTH, Peter
|
|
|
Post by rikky on Dec 27, 2018 15:33:59 GMT 1
I see. Well, after the FF D8 FF E0 I get 3B BE 8A D1 A2 B6 BA B AD DA 5B 5D 75 55 64 B7 B8 B2 EF 80 which doesn't make sense, for doesn't exist. Should be either : FF D8 FF E0 s1 s2 4A 46 49 46 00 ... or : FF D8 FF E0 FF E0 s1 s2 4A 46 58 58 00 ... So, YES it is a JFIF, but NO it is not a JFIF Okee, I leave it. I'm not going to invent another exiv2. For it already exists. Rik.
|
|