Page 1 of 1

What is the simplest way of saving pictures in small files?

Posted: 24 Apr 2016 7:25
by Ferenc Nagy

Code: Select all

territory_gb:getOuterRect()=RCT, my_picture:=vpi::pictGetFromWin(getVpiWindow(),RCT), % capture filename::setPath("Initial.bmp",DirectoryName)=SavedHere, vpi::pictSave(my_picture,SavedHere),
The above code fragment generates a bitmap iwhose size is several hundred thousand bytes.
I know the command line parameters of the irfanview program.
I could insert a createProcess or shell_api::shellExecute : (hwnd Window, string Operation, string File, string Parameters) call to this batch file to convert the huge bmp file to a much smaller png file then delete it.
I know another converter the http://fileminimizer-pictures.en.softonic.com/ :-( but I do not know its command line syntax.

I have to set the decreasing of the color depth manually for Irfanview. Fileminimizer does it without user interaction.

How can I quickly convert my picture to png format using the Visual Prolog packages only?

Posted: 24 Apr 2016 9:01
by Kari Rastas
I have used these.

Code: Select all

predicates     savePictureToFile : (vpiDomains::picture, string FileName, string EncoderType) procedure (i,i,i) language stdcall as "savePictureToFile".     %     %@short Saves a picture in a file with the wanted picture format     %     %@detail Saves a picture in a file with the wanted picture format     %     %Possible formats are bmp, gif, jpeg, tiff and png     %     %@example     %  PICTURE = O: getPicture(),     %  picCore::savePictureToFile(PICTURE,"example1.jpg","jpeg"),     %  picCore::savePictureToFile(PICTURE,"example2.bmp","bmp"),     %  picCore::savePictureToFile(PICTURE,"example3.tif","tiff"),     %  picCore::savePictureToFile(PICTURE,"example4.png","png"),     %     %@end     %       savePictureToFileJPEG : (vpiDomains::picture, string FileName) procedure (i,i) language stdcall as "savePictureToFileJPEG".     %     %@short Saves a picture in a file with jpeg format     %     %@detail Saves a picture in a file with jpeg format     %     %@example     %  PICTURE = O: getPicture(),     %  picCore::savePictureToFileJPEG(PICTURE,"example12.jpg"),     %     %@end     %       pictureFileToStringForHtml:(string PictureFileName,string PctureType,string NameText,unsigned Width,unsigned Height) -> string PicStr procedure (i,i,i,i,i) language stdcall as "pictureFileToStringForHtml".     %     %@short Produces from a picture file a string to be embedded in a html page     %     %@detail Produces from a picture file a string to be embedded in a html page.     %     %<img src=\"data:image/%;base64,%s\" alt=\"%s\" width=\"%\" height=\"%\">     %     %@example     %  PICTURE = O: getPicture(),     %  picCore::pictureFileToStringForHtml("example12.jpg","Export to USA in 2015",500, 250) = PictureStr,     %     %@end     %       pictureToStringForHtml:(vpiDomains::picture [in],string NameText [in],unsigned Width [in],unsigned Height [in]) -> string PicStr procedure (i,i,i,i) language stdcall as "pictureToStringForHtml".     %     %@short Produces from a picture a string to be embedded in a html page     %     %@detail Produces from a picture a string to be embedded in a html page.     %     %<img src=\"data:image/%;base64,%s\" alt=\"%s\" width=\"%\" height=\"%\">     %     %@example     %  PICTURE = O: getPicture(),     %  picCore::pictureToStringForHtml(PICTURE,"Export to USA in 2015",500, 250) = PictureStr,     %     %@end     % clauses     savePictureToFile(PIC,FileName,OEnc):-         Enc = string::toUpperCase(OEnc),         Enc in ["JPEG","BMP","TIFF","GIF","PNG","WMF","EMF","ICON"],!,         GdiPlusToken = gdiplus::startup(),             gpPictToImage(PIC, Image),             ImageClone = Image:clone(),             Image : dispose(),             gdiplus :: imageCodecInfo(JpegId, _, _, _, _, _, _, _, _, _, _, _, _) = getEncoder(Enc, gdiplus::imageEncoders),             ImageClone : saveToFile(FileName, JpegId, uncheckedConvert(gdiplus::encoderParameters, null)),             ImageClone : dispose(),         gdiplus :: shutdown(GdiPlusToken),         memory::garbageCollect().       savePictureToFile(_,_,_).   clauses     savePictureToFileJPEG(PIC,FileName):-         GdiPlusToken = gdiplus::startup(),             gpPictToImage(PIC, Image),             gdiplus :: imageCodecInfo(JpegId, _, _, _, _, _, _, _, _, _, _, _, _) = getEncoder("JPEG", gdiplus::imageEncoders),             Image : saveToFile(FileName, JpegId, uncheckedConvert(gdiplus::encoderParameters, null)),             Image : dispose(),         gdiplus :: shutdown(GdiPlusToken),         _ = vpi::processEvents(),         memory::garbageCollect().   class predicates    getEncoder : (string FormatDescription, gdiplus::imageCodecInfo* EncoderList) -> gdiplus::imageCodecInfo Encoder.   clauses     getEncoder(FormatDescription, [Encoder|_]) = Encoder :-         gdiplus::imageCodecInfo(_, _, _, _, FormatDescription, _, _, _, _, _, _, _, _) = Encoder,         !.       getEncoder(FormatDescription, [_|Rest]) = getEncoder(FormatDescription, Rest).       getEncoder(FormatDescription, []) = _ :-         common_exception::raise_errorf(classInfo, predicate_name(), "Unsupported image format '%'", FormatDescription).    class predicates      gpPictToImage : ( vpiDomains::picture Pict [in], image Image [out]).    clauses     gpPictToImage(Pict, Image):-         PictBin = vpi::pictToBin(Pict),         MemSize = binary::getSize(PictBin),         HGlobal = memory_native::globalAlloc(memory_native::gmem_GHND, convert(unsigned, MemSize)),         % GHND = GMEM_MOVEABLE + GMEM_ZEROINIT = 0x0002 + 0x0040         Pointer = memory_native::globalLock(HGlobal),         PointerBin = uncheckedConvert(pointer, PictBin),         memory::copy(Pointer, PointerBin, MemSize),         _ = iStream_api::createStreamOnHGlobal(HGlobal, 1, Stream),         Image = image::createFromStream(Stream),         _ = memory_native::globalUnlock(HGlobal).   clauses     pictureFileToStringForHtml(PictureFile,Type,NameText,Width,Height) =PicStr:-         file::existFile(PictureFile),         BIN = cryptography::base64_encode(file::readBinary(PictureFile)),         PicStr = string::format("\n<img src=\"data:image/%;base64,%s\" alt=\"%s\" width=\"%\" height=\"%\">\n",                                             Type,                                             BIN,                                             NameText,                                             Width,                                             Height),!.       pictureFileToStringForHtml(_PictureFile,_Type,_NameText,_Width,_Height) ="".   clauses     pictureToStringForHtml(Pict,NameText,Width,Height) =PicStr:-         savePictureToFile(Pict,"workpic.jpg","jpeg"),         pictureFileToStringForHtml("workpic.jpg","jpeg",NameText,Width,Height) =PicStr.
Example of a picture created as Visual Prolog picture and saved in png format - size 26 kB.

Posted: 24 Apr 2016 12:15
by Ferenc Nagy
Thank you, Kari

I have made a new Picture class using your code.
I have commented out my picture saving into BMP files and inserted my calls to the Picture module.
See lines marked by
% <====== comment
from the right.

Code: Select all

saveDataGroup(DirectoryName,save_initial_state_cb) = SavedHere :-         show_generation_int:setInteger(1),         written_chronicle:drawSnapshot(1)=InitialSnapShot,         alive_in_shown_int:setInteger(InitialSnapShot:alive_count),         territory_gb:getOuterRect()=RCT,         my_picture:=vpi::pictGetFromWin(getVpiWindow(),RCT), % capture         filename::setPath("Initial.png",DirectoryName)=SavedHere,         picture::savePictureToFile(my_picture,SavedHere,"png"), % <======         % filename::setPath("Initial.bmp",DirectoryName)=SavedHere,         % vpi::pictSave(my_picture,SavedHere),         my_picture:=erroneous,         show_generation_int:setInteger(written_chronicle:generation),         written_chronicle:drawSnapshot(written_chronicle:generation)=FinalSnapShot,         alive_in_shown_int:setInteger(FinalSnapShot:alive_count).     saveDataGroup(DirectoryName,save_final_state_cb) = SavedHere :-         save_final_state_cb:getCheckedState()=checkButton::checked(),         if show_generation_int:tryGetInteger()<written_chronicle:generation then             show_generation_int:setInteger(written_chronicle:generation),             written_chronicle:drawSnapshot(written_chronicle:generation)=FinalSnapShot,             alive_in_shown_int:setInteger(FinalSnapShot:alive_count)         end if,         territory_gb:getOuterRect()=RCT,         my_picture:=vpi::pictGetFromWin(getVpiWindow(),RCT), % capture         filename::setPath("Final.png",DirectoryName)=SavedHere,         picture::savePictureToFile(my_picture,SavedHere,"png"),  % <======         % filename::setPath("Initial.bmp",DirectoryName)=SavedHere,         % vpi::pictSave(my_picture,SavedHere),         my_picture:=erroneous.
Attachments:
Size reduction by File Minimizer is not longer crucial. The whole screen cannot be reduced.
Initial state of a wolf-goat-donkey life game saved by Kari's procedures.
Intermediate state of a wolf-goat-donkey life game saved by Kari's procedures.
Final state of a wolf-goat-donkey life game saved by Kari's procedures.
I have three questions.
1) Why do you need
language stdcall
in the predcate declaration?

Code: Select all

savePictureToFile : (vpiDomains::picture, string FileName, string EncoderType) procedure (i,i,i) language stdcall as "savePictureToFile".
2) There are two predicate names above. Can they be different?
3) Suppose I have two differerent names,

Code: Select all

nameA : (vpiDomains::picture, string FileName, string EncoderType) procedure (i,i,i) language stdcall as "nameB".
How can I call the predicate, using NameA(...) or NameB(...) ?

Posted: 24 Apr 2016 15:20
by Kari Rastas
1) Why do you need
Quote:
language stdcall

To save time I picked the code from one of my DLL's. Naturally "outside" a dll there is no need for the stdcall part.