Compress and timestamp your pictures to gain disk space
I was running out of space again on my notebook. As years go by, digital cameras can take pictures with more megapixels, but that means they take up more space.
Thus my pictures from 10 years ago are much smaller than this year’s.
Since I have multiple copies of my picture collection (28,000!) I didn’t mind modifying the notebook’s copy. Also, since the notebook resolution is 1400 X 1050, and I only ever display the notebook pictures on the notebook screen, the camera picture’s resolution 3072 X 2074 (Canon Powershot SD800) included more info than I needed.
The code resulted in most pictures compressing about 80%! You can vary the quality parameter and try it yourself. Also, my disk contains all the movies taken by the camera too, and these aren’t touched by the code.
So I ran the code below and gained 5 Gigabytes of storage! Not bad.
The code uses the GDIPlus class library to load, compress and store the file. This changes the file timestamp, so the code also preserves the original timestamp.
See also:
Recompress your digital pictures to save space
Resize your pictures for your phone or pocket pc
cRoot=ADDBS("d:\pictures\2006\")
recurdir(cRoot)
?"Done",DATETIME()
PROCEDURE recurdir(cBasePath)
LOCAL n,i
LOCAL aa[1]
?cbasePath
n=ADIR(aa,cBasePath+"*.*","D")
FOR i = 1 TO n
IF "D"$aa[i,5]
IF LEFT(aa[i,1],1)<>"."
recurdir(cBasePath+aa[i,1]+"\")
ENDIF
ELSE
IF LOWER(JUSTEXT(aa[i,1]))="jpg"
recompress(cBasePath+aa[i,1])
retimestamp("d:\t.jpg",CTOT(DTOC(aa[i,3])+" "+aa[i,4]))
COPY FILE d:\t.jpg TO (cBasePath+aa[i,1])
ENDIF
ENDIF
ENDFOR
RETURN
PROCEDURE recompress(cPict as String)
LOCAL aa[1]
cOutfile="d:\t.jpg"
LOCAL oImage as gpImage OF (HOME()+"ffc\_gdiplus")
oImage=NEWOBJECT("gpImage",HOME()+"ffc\_gdiplus","",cpict)
oImage.SaveToFile(cOutfile,"image/jpeg","Quality=20")
ADIR(aa,cOutfile)
nSizeNew=aa[1,2]
ADIR(aa,cPict)
nSizeOrig=aa[1,2]
?cPict
??" Orig Size = ",TRANSFORM(nSizeOrig,"999,999,999")
??" New Size = ",TRANSFORM(nSizeNew,"999,999,999")
* ??" # bytes smaller = ", TRANSFORM(nSizeOrig - nSizeNew,"999,999,999")
??" # times smaller", TRANSFORM(nSizeOrig / nSizeNew)
??" % savings=", TRANSFORM(100*(nSizeOrig - nSizeNew)/nSizeOrig )
*! &cOutfile
RETURN
*From WINNT.H:
#define FILE_SHARE_READ 0x00000001
#define FILE_SHARE_WRITE 0x00000002
#define FILE_SHARE_DELETE 0x00000004
#define FILE_ATTRIBUTE_READONLY 0x00000001
#define FILE_ATTRIBUTE_HIDDEN 0x00000002
#define FILE_ATTRIBUTE_SYSTEM 0x00000004
#define FILE_ATTRIBUTE_DIRECTORY 0x00000010
#define FILE_ATTRIBUTE_ARCHIVE 0x00000020
#define FILE_ATTRIBUTE_DEVICE 0x00000040
#define FILE_ATTRIBUTE_NORMAL 0x00000080
#define FILE_ATTRIBUTE_TEMPORARY 0x00000100
#define FILE_ATTRIBUTE_SPARSE_FILE 0x00000200
#define FILE_ATTRIBUTE_REPARSE_POINT 0x00000400
#define FILE_ATTRIBUTE_COMPRESSED 0x00000800
#define FILE_ATTRIBUTE_OFFLINE 0x00001000
#define FILE_ATTRIBUTE_NOT_CONTENT_INDEXED 0x00002000
#define FILE_ATTRIBUTE_ENCRYPTED 0x00004000
#define FILE_WRITE_ATTRIBUTES 0x100
#define GENERIC_WRITE (0x40000000)
#define GENERIC_READ (0x80000000)
*From winbase.h:
#define CREATE_NEW 1
#define CREATE_ALWAYS 2
#define OPEN_EXISTING 3
#define OPEN_ALWAYS 4
#define TRUNCATE_EXISTING 5
PROCEDURE ReTimeStamp(cFilename as string, dt as Datetime)
DECLARE integer CreateFile in win32api string, integer dwDesiredAccess, integer dwShareMode, integer security, ;
integer dwCreationDisposition, integer FlagsAttrs, integer hTemplate
DECLARE INTEGER CloseHandle in win32api integer hFile
DECLARE integer SystemTimeToFileTime IN WIN32API string , string @
DECLARE INTEGER SetFileTime IN kernel32;
INTEGER hFile, STRING lpCreationTime,;
STRING lpLastAccessTime, STRING lpLastWriteTime
DECLARE INTEGER SystemTimeToFileTime IN kernel32;
STRING lpSystemTime, STRING @lpFileTime
DECLARE INTEGER LocalFileTimeToFileTime IN kernel32;
STRING lpLocalFileTime, STRING @lpFileTime
DECLARE integer GetLastError in win32api
cFileTime = SPACE(8)
cSysTime=BINTOC(YEAR(dt),"2rs") + ;
BINTOC(MONTH(dt),"2rs") + ;
BINTOC(DOW(dt,0),"2rs") + ;
BINTOC(DAY(dt),"2rs") + ;
BINTOC(HOUR(dt),"2rs") + ;
BINTOC(MINUTE(dt),"2rs") + ;
REPLICATE(CHR(0),4)
SystemTimeToFileTime(cSysTime, @cFileTime)
LocalFileTimeToFileTime(cFileTime, @cFileTime)
hFile = CreateFile(cFilename, GENERIC_WRITE+GENERIC_READ,FILE_SHARE_READ, 0, OPEN_EXISTING, 0,0)
SetFileTime(hFile , cFileTime, cFileTime,cFileTime)
CloseHandle(hFile)
RETURN
Comments
Anonymous
March 13, 2008
PingBack from http://pocket-pc.jfcforum.com/2008/03/13/compress-and-timestamp-your-pictures-to-gain-disk-space/Anonymous
March 14, 2008
The comment has been removedAnonymous
March 14, 2008
The comment has been removed