PDA

View Full Version : Save image as bmp, jpg, tiff, png



wila
16-Jun-2013, 05:13 AM
Hi,

AFAIK this feature is still not available in the library, I keep on forgetting sharing the solution I wrote for this and I guess it is best shared here instead of at vdf-guidance.

This was written for an old version of the library, so you might have to adjust a bit of code for the latest library.
Anyhow.. here's the code, let me know if you are missing something for being able to compile as I might have missed copying out a detail.



// To extend DAWs graphics library 1.0 for supporting save operations
//
// Created: 2012-02-20
//
//
// Author: Wil van Antwerpen
//
//

//Define ENCODER_JPEG for "{557CF401-1A04-11D3-9A73-0000F81EF32E}"

Define CS_BMP_Mimetype for "image/bmp"
Define CS_JPG_Mimetype for "image/jpeg"
Define CS_GIF_Mimetype for "image/gif"
Define CS_TIF_Mimetype for "image/tiff"
Define CS_PNG_Mimetype for "image/png"

// http://msdn.microsoft.com/en-us/library/ms534081(v=vs.85).aspx
// Status GetImageEncodersSize(
// __out UINT *numEncoders,
// __out UINT *size
//);
//
//

#IFNDEF get_GdipGetImageEncodersSize
External_Function GdipGetImageEncodersSize "GdipGetImageEncodersSize" gdiplus.dll ;
Pointer numEncoders ;
Pointer size ;
Returns gpStatus
#ENDIF

//http://msdn.microsoft.com/en-us/library/ms534080(v=vs.85).aspx
//Status GetImageEncoders(
// __in UINT numEncoders,
// __in UINT size,
// __out ImageCodecInfo *encoders
//);

#IFNDEF get_GdipGetImageEncoders
External_Function GdipGetImageEncoders "GdipGetImageEncoders" gdiplus.dll ;
UInteger numEncoders ;
UInteger size ;
Pointer pImageCodeInfo ;
Returns gpStatus
#ENDIF

//http://msdn.microsoft.com/en-us/library/windows/desktop/aa373931(v=vs.85).aspx
//#IFNDEF _STRUCT_GUID
//Struct GUID
// Integer Data1
// Short Data2
// Short Data3
// Char[8] Data4
//End_Struct // GUID
//#ENDIF

// in c++ in wtypes.h you will find the line:
// typedef GUID CLSID;
// aka: the type CLSID is in reality just a GUID struct

#IFNDEF _STRUCT_tImageCodecInfo
Struct tImageCodecInfo
GUID CLSID
GUID formatID
Pointer pszwCodecName
Pointer pszwDllName
Pointer pszwFormatDescription
Pointer pszwFileNameExtension
Pointer pszwMimeType
DWord Flags
DWord Version
DWord SigCount
DWord SigSize
Pointer SigPattern
Pointer SigMask
End_Struct // tImageCodecInfo
#ENDIF


// Function : Based on WStrToStr, but changed to take an address as parameter.
// Purpose : Converts a Unicode to a OEM string
Function WPStrToStr Global Address pData Returns String
Integer iLength iResult
String sBuffer

// Get size of buffer
Move (WideCharToMultiByte(CP_OEMCP,0,pData,-1,0,0,0,0)) to iLength
If (iLength = 0) Function_Return ""

// Create output buffer
Move (Repeat(Character(0),iLength)) to sBuffer

// Do actuall conversion
Move (WideCharToMultiByte(CP_OEMCP,0,pData,-1,AddressOf(sBuffer),iLength,0,0)) to iResult
If (iResult = 0) Function_Return ""

Function_Return sBuffer
End_Function




//
// This function will enumerate through the available encoders installed on the PC and
// for each encoder compare its mimetype with the parameter passed.
// If the mimetype has been found then it will retrieve the CLSID structure and return
// this as a copy of the CLSID.
//
Function EncoderCodecCLSID String sMimeType Returns Address
GUID CLSID // A CLSID type is in reality a GUID type
Integer ICIsize
Integer iResult
UInteger numEncoders
UInteger xSize j
Pointer pnumEncoders
Pointer pSize
tImageCodecInfo xImageCodecInfo
Address pImageCodecInfo
Pointer pCodecArray
Boolean bRetVal
Boolean bOk
String sCodecMimeType

Move (SizeOfType(tImageCodecInfo)) to ICIsize
Move 0 to xSize
Move 0 to numEncoders
Move 0 to CLSID.Data1
Move (AddressOf(xSize)) to pSize
Move (AddressOf(numEncoders)) to pnumEncoders

Move (GdipGetImageEncodersSize(pNumEncoders,pSize)) to iResult
If (iResult=0 and xSize>0 and numEncoders>0) Begin
Move (Alloc(xSize)) to pImageCodecInfo

Move (GdipGetImageEncoders(numEncoders,xSize,pImageCode cInfo)) to iResult
If (iResult=0) Begin
For j from 0 to (numEncoders-1)
Move (pImageCodecInfo+(j*ICIsize)) to pCodecArray
Move (MemCopy (AddressOf(xImageCodecInfo), pCodecArray, ICIsize)) to bOk
If (not (bOk)) Begin
Error DFERR_PROGRAM "The MemCopy function failed (EncoderCodecCLSID)"
End
Move (WPStrToStr(xImageCodecInfo.pszwMimeType)) to sCodecMimeType
If (sCodecMimeType=sMimeType) Begin
// We found our codec
Move xImageCodecInfo.CLSID to CLSID
End
Loop
End
Move (Free(pImageCodecInfo)) to bRetval
End
Function_Return CLSID
End_Function // EncoderCodecCLSID


//
// Returns the 3 letter file extension for the following mimetypes
// The extension contains NO dot. So for "image/jpeg" the function will
// return "jpg"
//
// Supported mimetypes are:
// image/bmp
// image/jpeg
// image/gif
// image/tiff
// image/png
Function MimeTypeToFileType String sMimeType Returns String
String sExtension

Move "" To sExtension
Case Begin
Case (sMimeType=CS_BMP_Mimetype)
Move "bmp" To sExtension
Case Break
Case (sMimeType=CS_JPG_Mimetype)
Move "jpg" To sExtension
Case Break
Case (sMimeType=CS_GIF_Mimetype)
Move "gif" To sExtension
Case Break
Case (sMimeType=CS_TIF_Mimetype)
Move "tif" To sExtension
Case Break
Case (sMimeType=CS_PNG_Mimetype)
Move "png" To sExtension
Case Break
Case End
Function_Return sExtension
End_Function // MimeTypeToFileType


//
// Takes the 3 letter file extension and returns one of the following mimetypes
// The extension contains NO dot. So for "jpg" the function will
// return "image/jpeg"
// Returns "" if no mimetype was found
//
// Supported mimetypes are:
// image/bmp
// image/jpeg
// image/gif
// image/tiff
// image/png
Function FileTypeToMimeType String sExtension Returns String
String sMimeType

Move "" To sMimeType
Case Begin
Case (sExtension="bmp")
Move CS_BMP_Mimetype To sMimeType
Case Break
Case (sExtension="jpg")
Move CS_JPG_Mimetype To sMimeType
Case Break
Case (sExtension="gif")
Move CS_GIF_Mimetype To sMimeType
Case Break
Case (sExtension="tif")
Move CS_TIF_Mimetype To sMimeType
Case Break
Case (sExtension="png")
Move CS_PNG_Mimetype To sMimeType
Case Break
Case End
Function_Return sMimeType
End_Function // FileTypeToMimeType

//
// If your current image has a filename then it cannot overwrite
// the current file. You will have to save it using a different
// filename.
// The filetype that is being used is determined based on the last
// 3 characters of your filename
//
// Returns 0 if saved successful or the gpstatus error if not.
// gpStatus errors are defined in DAWs cGDIPlus.h file
// The following codes have been added to that:
// 30 = sFileName is blank
// 31 = The file extension used is not supported
//
Function SaveImageToFile String sFileName Returns Integer
String sFileType
String sMimeType
String sFileNameW
Address pFileNameW
Address pCLSID
Handle hoImage
Integer iResult
Pointer pObject
GUID CLSID

If (sFileName<>"") Begin
// Get GDI+ object
Get phoImage to hoImage
If (hoImage) Begin
Get Private.ppObject of hoImage to pObject
End

Move (lowercase(Right(sFileName,3))) to sFileType
Get FileTypeToMimeType sFileType To sMimeType
If (sMimeType<>"") Begin
Get EncoderCodecCLSID sMimeType to CLSID

Move (AddressOf(CLSID)) to pCLSID
Get StrToWStr sFileName to sFileNameW
Move (AddressOf(sFileNameW)) to pFileNameW
Move (GdipSaveImageToFile(pObject,pFileNameW,pCLSID,0)) to iResult
End
Else Move 31 To iResult
End
Else Move 30 To iResult

Function_Return iResult
End_Function // SaveImageToFile



cheers,

--
Wil

Vincent Oorsprong
16-Jun-2013, 06:34 AM
Wil,

Thanks, stored for review and adding.

Bob Worsley
16-Jun-2013, 09:03 AM
Nice!

Richard Hogg
16-Jun-2013, 05:22 PM
Thanks Wil your contribution is much appreciated.

Cheers
Richard

chuckatkinson
17-Jun-2013, 11:31 AM
Thanks Wil - very useful addition. Hope it makes into the next standard release of the library.

Vincent Oorsprong
17-Jun-2013, 12:10 PM
It is saved in the folder for inclusion.

adlike
29-Aug-2013, 02:03 AM
this software can save images to many formats,pretty good library. thank you for sharing your codes on image saving. i also like to offer some of my sample codes on image saving in c# (http://www.rasteredge.com/how-to/csharp-imaging/imaging-saving-printing/). hope it helps you to make everything perfect.