function ScalePicStreamToFile(aStream: TStream; aFilename: UnicodeString; destWidth, destHeight: Integer; aWICImagingFactory: IWICImagingFactory; OverWrite: Boolean = False): boolean;
var
hr: HRESULT;
isLocalFactory: Boolean;
// for proper scaling
xfactor, yfactor:double;
origWidth, origHeight: Cardinal;
newWidth, newHeight: Cardinal;
// reading the source image
SourceAdapter: IStream;
BitmapDecoder: IWICBitmapDecoder;
DecodeFrame: IWICBitmapFrameDecode;
SourceBitmap: IWICBitmap;
SourceScaler: IWICBitmapScaler;
// writing the resized image
DestStream: TMemoryStream;
DestAdapter: IStream;
DestWICStream: IWICStream;
BitmapEncoder: IWICBitmapEncoder;
EncodeFrame: IWICBitmapFrameEncode;
Props: IPropertyBag2;
begin
result := False;
if Not Overwrite
and FileExists(aFilename)
then
begin
result := True;
exit;
end;
isLocalFactory := (aWICImagingFactory =
nil);
if isLocalFactory
then
CoCreateInstance(CLSID_WICImagingFactory,
nil, CLSCTX_INPROC_SERVER
or
CLSCTX_LOCAL_SERVER, IUnknown, aWICImagingFactory);
// read the image data from stream
SourceAdapter := TStreamAdapter.Create(aStream);
hr := aWICImagingFactory.CreateDecoderFromStream(SourceAdapter, guid_null, WICDecodeMetadataCacheOnDemand, BitmapDecoder);
if Succeeded(hr)
then hr := BitmapDecoder.GetFrame(0, DecodeFrame);
if Succeeded(hr)
then hr := aWICImagingFactory.CreateBitmapFromSource(DecodeFrame, WICBitmapCacheOnLoad, SourceBitmap);
if Succeeded(hr)
then hr := SourceBitmap.GetSize(origWidth, origHeight);
// calculate proper scaling
xfactor:= (destWidth) / origWidth;
yfactor:= (destHeight) / origHeight;
if xfactor > yfactor
then
begin
newWidth := round(origWidth * yfactor);
newHeight := round(origHeight * yfactor);
end else
begin
newWidth := round(origWidth * xfactor);
newHeight := round(origHeight * xfactor);
end;
// scale the original image
if Succeeded(hr)
then hr := aWICImagingFactory.CreateBitmapScaler(SourceScaler);
if Succeeded(hr)
then hr := SourceScaler.Initialize(SourceBitmap, NewWidth, NewHeight, WICBitmapInterpolationModeFant);
if Succeeded(hr)
then
begin
// Reading and scaling the original image was successful.
// Now try to save the scaled image
DestStream := TMemoryStream.create;
try
// create new WICStream
DestAdapter := TStreamAdapter.Create(DestStream);
if Succeeded(hr)
then hr := aWICImagingFactory.CreateStream(DestWICStream);
if Succeeded(hr)
then hr := DestWICStream.InitializeFromIStream(DestAdapter);
// create and prepare JPEG-Encoder
if Succeeded(hr)
then hr := aWICImagingFactory.CreateEncoder(GUID_ContainerFormatJpeg, guid_null, BitmapEncoder);
if Succeeded(hr)
then hr := BitmapEncoder.Initialize(DestWICStream, WICBitmapEncoderNoCache);
if Succeeded(hr)
then hr := BitmapEncoder.CreateNewFrame(EncodeFrame, Props);
if Succeeded(hr)
then hr := EncodeFrame.Initialize(Props);
if Succeeded(hr)
then hr := EncodeFrame.SetSize(newWidth, newHeight);
// write image data
if Succeeded(hr)
then hr := EncodeFrame.WriteSource(SourceScaler,
nil);
if Succeeded(hr)
then hr := EncodeFrame.Commit;
if Succeeded(hr)
then hr := BitmapEncoder.Commit;
// finally save the stream to the destination file
if Succeeded(hr)
then
try
DestStream.SaveToFile(aFilename);
result := True;
except
// silent exception here, but (try to) delete the destination file, if it exists
result := False;
if FileExists(aFilename)
then DeleteFile(aFilename);
end;
finally
DestStream.Free;
end;
end;
if isLocalFactory
then
aWICImagingFactory._Release;
end;