Skip to content

Commit 05716b3

Browse files
committed
Added example 7
1 parent b43a472 commit 05716b3

13 files changed

+513
-14
lines changed

README.md

+4
Original file line numberDiff line numberDiff line change
@@ -31,5 +31,9 @@ These example C++ and C# projects show how to use the Windows Imaging Component
3131
**Language:** C#
3232
**Description:** Similar as example 4 but it uses the NuGet package [stakx.WIC](https://www.nuget.org/packages/stakx.WIC/) instead of the Microsoft WicCop interop library.
3333

34+
## Example 7
35+
**Language:** C++
36+
**Description:** Shows how to save an image by using a [custom WIC codec](https://github.com/ReneSlijkhuis/example-wic-codec).
37+
3438
## License
3539
Released under the [MIT license](https://en.wikipedia.org/wiki/MIT_License).

clean.bat

+4
Original file line numberDiff line numberDiff line change
@@ -20,4 +20,8 @@ cd ..
2020

2121
cd example_6
2222
call clean.bat
23+
cd ..
24+
25+
cd example_7
26+
call clean.bat
2327
cd ..

example_1/WicClient.cpp

+9-9
Original file line numberDiff line numberDiff line change
@@ -53,11 +53,11 @@ void WicReadFrame( const wstring& filename )
5353
pFactory->CreateDecoderFromFilename( filename.c_str( ), NULL, GENERIC_READ, WICDecodeMetadataCacheOnDemand, &pDecoder );
5454
// Check the return value to see if:
5555
// - The specified file exists and can be read.
56-
// - A decoder is found for this file format.
56+
// - A decoder is found for this file format.
5757

5858
UINT frameCount = 0;
5959
pDecoder->GetFrameCount( &frameCount );
60-
60+
6161
pDecoder->GetFrame( 0, &pFrame );
6262
// The zero-based index should be smaller than the frame count.
6363

@@ -67,36 +67,36 @@ void WicReadFrame( const wstring& filename )
6767

6868
WICPixelFormatGUID pixelFormatGUID;
6969
pFrame->GetPixelFormat( &pixelFormatGUID );
70-
70+
7171
// The frame can use many different pixel formats.
7272
// You can copy the raw pixel values by calling "pFrame->CopyPixels( )".
7373
// This method needs a buffer that can hold all bytes.
7474
// The total number of bytes is: width x height x bytes per pixel
7575

7676
// The disadvantage of this solution is that you have to deal with all possible pixel formats.
7777

78-
// You can make your life easy by converting the frame to a pixel format of
78+
// You can make your life easy by converting the frame to a pixel format of
7979
// your choice. The code below shows how to convert the pixel format to 24-bit RGB.
80-
80+
8181
pFactory->CreateFormatConverter( &pFormatConverter );
8282

8383
pFormatConverter->Initialize( pFrame, // Input bitmap to convert
8484
GUID_WICPixelFormat24bppRGB, // Destination pixel format
8585
WICBitmapDitherTypeNone, // Specified dither pattern
86-
nullptr, // Specify a particular palette
86+
nullptr, // Specify a particular palette
8787
0.f, // Alpha threshold
8888
WICBitmapPaletteTypeCustom ); // Palette translation type
8989

9090
UINT bytesPerPixel = 3; // Because we have converted the frame to 24-bit RGB
9191
UINT stride = width * bytesPerPixel;
92-
UINT size = width * height * bytesPerPixel; // The size of the required memory buffer for
92+
UINT size = width * height * bytesPerPixel; // The size of the required memory buffer for
9393
// holding all the bytes of the frame.
9494

9595
vector<BYTE> bitmap( size ); // The buffer to hold all the bytes of the frame.
9696
pFormatConverter->CopyPixels( NULL, stride, size, bitmap.data( ) );
9797

9898
// Note: the WIC COM pointers should be released before 'CoUninitialize( )' is called.
99-
}
99+
}
100100
CoUninitialize( );
101101
}
102102

@@ -105,7 +105,7 @@ void WicReadFrame( const wstring& filename )
105105
int main( )
106106
{
107107
WicReadFrame( L"<filename>" );
108-
108+
109109
return 0;
110110
}
111111

example_2/Program.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ private static void ConvertToPng(string filename)
4949
encoder.Frames.Add(frame);
5050

5151
using (var outFile = File.OpenWrite(filename + ".png"))
52-
{
52+
{
5353
encoder.Save(outFile);
5454
}
5555
}

example_5/WicClient.cpp

+4-4
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ void WicReadFrame( const wstring& filename )
5353
pFactory->CreateDecoderFromFilename( filename.c_str( ), NULL, GENERIC_READ, WICDecodeMetadataCacheOnDemand, &pDecoder );
5454
// Check the return value to see if:
5555
// - The specified file exists and can be read.
56-
// - A decoder is found for this file format.
56+
// - A decoder is found for this file format.
5757

5858
pDecoder->GetFrame( 0, &pFrame );
5959

@@ -68,7 +68,7 @@ void WicReadFrame( const wstring& filename )
6868

6969
PROPVARIANT variant;
7070
PropVariantInit( &variant );
71-
71+
7272
// IFD Metadata - Image width
7373
pMetadataReader->GetMetadataByName( L"/ifd/{ushort=256}", &variant );
7474
PropVariantClear( &variant );
@@ -86,7 +86,7 @@ void WicReadFrame( const wstring& filename )
8686
PropVariantClear( &variant );
8787

8888
// Note: the WIC COM pointers should be released before 'CoUninitialize( )' is called.
89-
}
89+
}
9090
CoUninitialize( );
9191
}
9292

@@ -95,7 +95,7 @@ void WicReadFrame( const wstring& filename )
9595
int main( )
9696
{
9797
WicReadFrame( L"<filename>" );
98-
98+
9999
return 0;
100100
}
101101

example_7/WicClient.cpp

+151
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
1+
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2+
//
3+
// MIT License
4+
//
5+
// Copyright(c) 2017 René Slijkhuis
6+
//
7+
// Permission is hereby granted, free of charge, to any person obtaining a copy
8+
// of this software and associated documentation files (the "Software"), to deal
9+
// in the Software without restriction, including without limitation the rights
10+
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11+
// copies of the Software, and to permit persons to whom the Software is
12+
// furnished to do so, subject to the following conditions:
13+
//
14+
// The above copyright notice and this permission notice shall be included in all
15+
// copies or substantial portions of the Software.
16+
//
17+
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18+
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19+
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20+
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21+
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22+
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23+
// SOFTWARE.
24+
//
25+
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
26+
27+
#include "stdafx.h"
28+
29+
#include <vector>
30+
#include <atlbase.h>
31+
#include <initguid.h>
32+
#include <Wincodec.h>
33+
34+
using namespace std;
35+
36+
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
37+
//
38+
// Include header: Wincodec.h
39+
// Add to linker input: Windowscodecs.lib
40+
//
41+
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
42+
43+
// GUID of the Lisa image format (this should be known by applications that want to write this format).
44+
// {91DFBD70-3D2C-440F-B297-1E2097D4A833}
45+
DEFINE_GUID(GUID_LisaContainerFormat, 0x91dfbd70, 0x3d2c, 0x440f, 0xb2, 0x97, 0x1e, 0x20, 0x97, 0xd4, 0xa8, 0x33);
46+
47+
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
48+
49+
void SaveAsLisa( const wstring& filename )
50+
{
51+
CoInitialize( nullptr );
52+
{
53+
CComPtr<IWICImagingFactory> pFactory;
54+
CComPtr<IWICBitmapDecoder> pDecoder;
55+
CComPtr<IWICBitmapEncoder> pEncoder;
56+
CComPtr<IWICBitmapFrameDecode> pFrameDecode;
57+
CComPtr<IWICBitmapFrameEncode> pFrameEncode;
58+
CComPtr<IWICFormatConverter> pFormatConverter;
59+
CComPtr<IWICStream> pFileStream;
60+
CComPtr<IPropertyBag2> pPropertyBag;
61+
62+
CoCreateInstance( CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER, IID_IWICImagingFactory, (LPVOID*)&pFactory );
63+
64+
// Read the specified file by using an installed WIC codec.
65+
66+
pFactory->CreateDecoderFromFilename( filename.c_str( ), NULL, GENERIC_READ, WICDecodeMetadataCacheOnDemand, &pDecoder );
67+
// Check the return value to see if:
68+
// - The specified file exists and can be read.
69+
// - A decoder is found for this file format.
70+
71+
UINT frameCount = 0;
72+
pDecoder->GetFrameCount( &frameCount );
73+
74+
pDecoder->GetFrame( 0, &pFrameDecode );
75+
76+
UINT width = 0;
77+
UINT height = 0;
78+
pFrameDecode->GetSize( &width, &height );
79+
80+
WICPixelFormatGUID pixelFormatSource;
81+
pFrameDecode->GetPixelFormat( &pixelFormatSource );
82+
83+
WICPixelFormatGUID pixelFormatDestination = GUID_WICPixelFormat24bppRGB;
84+
85+
// The frame can use many different pixel formats.
86+
// You can copy the raw pixel values by calling "pFrame->CopyPixels( )".
87+
// This method needs a buffer that can hold all bytes.
88+
// The total number of bytes is: width x height x bytes per pixel
89+
90+
// The disadvantage of this solution is that you have to deal with all possible pixel formats.
91+
92+
// You can make your life easy by converting the frame to a pixel format of
93+
// your choice. The code below shows how to convert the pixel format to 24-bit RGB.
94+
95+
pFactory->CreateFormatConverter( &pFormatConverter );
96+
97+
pFormatConverter->Initialize( pFrameDecode, // Input bitmap to convert
98+
pixelFormatDestination, // Destination pixel format
99+
WICBitmapDitherTypeNone, // Specified dither pattern
100+
nullptr, // Specify a particular palette
101+
0.f, // Alpha threshold
102+
WICBitmapPaletteTypeCustom ); // Palette translation type
103+
104+
UINT bytesPerPixel = 3; // Because we have converted the frame to 24-bit RGB
105+
UINT stride = width * bytesPerPixel;
106+
UINT size = width * height * bytesPerPixel; // The size of the required memory buffer for
107+
// holding all the bytes of the frame.
108+
109+
vector<BYTE> bytes( size ); // The buffer to hold all the bytes of the frame.
110+
pFormatConverter->CopyPixels( NULL, stride, size, bytes.data( ) );
111+
112+
// Save the image in the Lisa format.
113+
// The Lisa WIC codec should be installed (see the link below).
114+
// https://github.com/ReneSlijkhuis/example-wic-codec
115+
116+
pFactory->CreateEncoder( GUID_LisaContainerFormat, NULL, &pEncoder );
117+
// Check the return value to see if an encoder is found for the specified file format.
118+
119+
pFactory->CreateStream( &pFileStream );
120+
121+
wstring output = filename + L".lisa";
122+
pFileStream->InitializeFromFilename( output.c_str( ), GENERIC_WRITE );
123+
124+
pEncoder->Initialize( pFileStream, WICBitmapEncoderNoCache );
125+
126+
pEncoder->CreateNewFrame( &pFrameEncode, &pPropertyBag );
127+
128+
pFrameEncode->SetPixelFormat( &pixelFormatDestination );
129+
130+
pFrameEncode->SetSize( width, height );
131+
132+
pFrameEncode->WritePixels( height, stride, size, bytes.data( ) );
133+
134+
pFrameEncode->Commit( );
135+
pEncoder->Commit( );
136+
137+
// Note: the WIC COM pointers should be released before 'CoUninitialize( )' is called.
138+
}
139+
CoUninitialize( );
140+
}
141+
142+
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
143+
144+
int main( )
145+
{
146+
SaveAsLisa( L"<filename>" );
147+
148+
return 0;
149+
}
150+
151+
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

example_7/WicClient.sln

+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
2+
Microsoft Visual Studio Solution File, Format Version 12.00
3+
# Visual Studio 14
4+
VisualStudioVersion = 14.0.25420.1
5+
MinimumVisualStudioVersion = 10.0.40219.1
6+
Project("{03004AAB-CA40-47C8-9513-6B2C08D196F0}") = "WicClient", "WicClient.vcxproj", "{47FFCF5F-0C55-4DA1-8630-C65944E92CB5}"
7+
EndProject
8+
Global
9+
GlobalSection(SolutionConfigurationPlatforms) = preSolution
10+
Debug|x64 = Debug|x64
11+
Debug|x86 = Debug|x86
12+
Release|x64 = Release|x64
13+
Release|x86 = Release|x86
14+
EndGlobalSection
15+
GlobalSection(ProjectConfigurationPlatforms) = postSolution
16+
{47FFCF5F-0C55-4DA1-8630-C65944E92CB5}.Debug|x64.ActiveCfg = Debug|x64
17+
{47FFCF5F-0C55-4DA1-8630-C65944E92CB5}.Debug|x64.Build.0 = Debug|x64
18+
{47FFCF5F-0C55-4DA1-8630-C65944E92CB5}.Debug|x86.ActiveCfg = Debug|Win32
19+
{47FFCF5F-0C55-4DA1-8630-C65944E92CB5}.Debug|x86.Build.0 = Debug|Win32
20+
{47FFCF5F-0C55-4DA1-8630-C65944E92CB5}.Release|x64.ActiveCfg = Release|x64
21+
{47FFCF5F-0C55-4DA1-8630-C65944E92CB5}.Release|x64.Build.0 = Release|x64
22+
{47FFCF5F-0C55-4DA1-8630-C65944E92CB5}.Release|x86.ActiveCfg = Release|Win32
23+
{47FFCF5F-0C55-4DA1-8630-C65944E92CB5}.Release|x86.Build.0 = Release|Win32
24+
EndGlobalSection
25+
GlobalSection(SolutionProperties) = preSolution
26+
HideSolutionNode = FALSE
27+
EndGlobalSection
28+
EndGlobal

0 commit comments

Comments
 (0)