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

Discussions related to Visual Prolog
User avatar
Ferenc Nagy
VIP Member
Posts: 289
Joined: 24 Apr 2007 12:26

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

Unread post by Ferenc Nagy » 24 Apr 2016 7:25

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?
TIA, Regards,
Frank Nagy

Kari Rastas
Active Member
Posts: 43
Joined: 4 Mar 2000 0:01

Unread post by Kari Rastas » 24 Apr 2016 9:01

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.
Attachments
USA_tuontiRU.png
USA_tuontiRU.png (24.87 KiB) Viewed 4451 times

User avatar
Ferenc Nagy
VIP Member
Posts: 289
Joined: 24 Apr 2007 12:26

Unread post by Ferenc Nagy » 24 Apr 2016 12:15

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(...) ?
Attachments
Initial .png
Initial .png (10.57 KiB) Viewed 4443 times
generation#19 .PNG
generation#19 .PNG (18.96 KiB) Viewed 4443 times
Final .png
Final .png (17.17 KiB) Viewed 4443 times
sizereduction.PNG
sizereduction.PNG (14.83 KiB) Viewed 4443 times
TIA, Regards,
Frank Nagy

Kari Rastas
Active Member
Posts: 43
Joined: 4 Mar 2000 0:01

Unread post by Kari Rastas » 24 Apr 2016 15:20

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.

Post Reply