概要

  • B/W2値データを画像として保存するサンプル。
  • 保存可能な形式は、BMP, GIF, JPG, PNG, TIF。
  • Win7(GDI+ 6.x)ではインデックスカラー、Vista(GDI+ 5.x)では32bitカラーで処理する。
    • インデックスカラーで処理するように色々調べたりしたけど、GIF や PNG だとインデックスカラーではあってもパレットが2個になってなくて効果はあんまりなかったかも。 (--;
  • エラー時にイベントログにメッセージを出す。
    • 登録先は「アプリケーション」、イベントソースは「WSH」、イベントIDは「0」で固定されている。
  • あれ?スタートアッププロジェクトって *.sln に記録されてるんじゃないのか。
    • 実行に失敗する場合は、スタートアッププロジェクトを「Tester」に変更して下さい。
  • ドット描画時に MAX_MATRIX_SIZE から食み出てないか確認するようにした。(2013/03/04)

ソース

  • &ref(): File not found: "GdiHelper.zip" at page "VisualC++/GdiHelper";

GdiHelper.h

すべてを展開すべてを収束
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
-
|
|
|
|
|
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
!
|
!
 
 
/**
	@mainpage GDI+ を簡便に利用する。
 
	B/W データを画像として保存する。
*/
#pragma once
 
#include <windows.h>
#include <string.h>
 
#ifdef GDIHELPER_EXPORTS
    #define EXPORT_GDIHELPER_SYMBOL __declspec(dllexport)
#else
    #define EXPORT_GDIHELPER_SYMBOL __declspec(dllimport)
#endif
 
/// マトリクスの最大サイズ
#define    MAX_MATRIX_SIZE    (100)
 
namespace TakeAsh {
 
/**
	GDI+ Helper
*/
class EXPORT_GDIHELPER_SYMBOL GdiHelper
{
public:
/// パターンを記録するマトリクス(PixelFormat1bppIndexed)
typedef BYTE MATRIX[MAX_MATRIX_SIZE][MAX_MATRIX_SIZE];
 
public:
    GdiHelper();    ///< コンストラクタ
    ~GdiHelper();    ///< デストラクタ
 
public:
    /**
		拡張子からイメージエンコーダーのクラスIDを得る。
		@retval	true	発見した。
		@retval	false	発見できなかった。
	*/
    bool GetEncoderClsIdByExt(
        const wchar_t *wsExtension,    ///< [in] 拡張子
        CLSID* pClsid                ///< [out] エンコーダクラスID
    );
 
    /**
		マトリクスを画像ファイルとして保存。
	*/
    bool saveMatrix(
        const wchar_t *fileName,    ///< [in] ファイル名
        const wchar_t *fileExt,        ///< [in] 拡張子
        MATRIX matrix,                ///< [in] マトリクス
        int size                    ///< [in] マトリクスのサイズ
    );
};
 
}
 
// EOF

GdiHelper.cpp

すべてを展開すべてを収束
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
-
|
|
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
!
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
-
|
|
-
|
|
|
|
!
|
|
|
|
|
|
|
|
-
|
|
!
|
|
-
|
|
!
|
|
|
|
-
|
|
-
|
|
|
|
!
!
|
|
|
|
!
|
|
-
-
|
!
!
|
|
|
|
|
-
|
|
|
|
|
|
-
|
|
-
|
!
!
|
|
|
|
|
|
|
-
|
|
|
|
|
|
|
|
|
|
-
|
|
|
|
|
|
|
!
|
|
|
|
|
|
|
|
-
-
-
|
!
!
!
|
|
-
|
-
|
|
|
!
!
|
|
|
|
!
|
!
 
 
// GdiHelper.cpp : DLL アプリケーション用にエクスポートされる関数を定義します。
//
 
#include "stdafx.h"
#include "resource.h"
#include <map>
#include "EventLogger.h"
#include "GdiHelper.h"
 
using namespace std;
 
// stdafx.h の「#define WIN32_LEAN_AND_MEAN」をコメントアウトしておくこと。
#include <gdiplus.h>
using namespace Gdiplus;
#pragma comment(lib, "gdiplus.lib")
 
#define    LIB_NAME    L"GDI+ Helper"
 
namespace TakeAsh {
 
/// GDI+ のステータスコード
const wchar_t *GDIStatus[] = {
    L"Ok", 
    L"Generic Error", 
    L"Invalid Parameter", 
    L"Out Of Memory", 
    L"Object Busy", 
    L"Insufficient Buffer", 
    L"Not Implemented", 
    L"Win32 Error", 
    L"Wrong State", 
    L"Aborted", 
    L"File Not Found", 
    L"Value Overflow", 
    L"Access Denied", 
    L"Unknown Image Format", 
    L"Font Family Not Found", 
    L"Font Style Not Found", 
    L"Not TrueType Font", 
    L"Unsupported Gdiplus Version", 
    L"Gdiplus Not Initialized", 
    L"Property Not Found", 
    L"Property Not Supported", 
    L"Profile Not Found", 
};
 
ULONG_PTR gdiToken;            ///< GDI+ スタートアップ時に受け取るトークン
GdiplusStartupInput gdiSI;    ///< GDI+ スタートアップ時に指定するオブジェクト
 
/// 拡張子とエンコーダクラスIDのセットの型定義
typedef map<wstring, CLSID> ImageEncorderMap;
 
/// 拡張子とエンコーダクラスIDのセットのインスタンス
ImageEncorderMap ImageEncorders;
 
/**
	PixelFormat1bppIndexed が使用できるかどうかのフラグ
	- true	Win7(GDI+ 6.x)
	- false	Vista(GDI+ 5.x)
*/
bool bCanBW;
 
GdiHelper::GdiHelper()
{
    gdiToken = NULL;
    Status stat = GdiplusStartup( &gdiToken, &gdiSI, NULL );
    if (stat != Ok){
        wchar_t msg[64] = L"";
        wsprintf( msg, LIB_NAME L": failed to initialize. <%d> [%s]\n", stat, GDIStatus[ stat ] );
        logMessage( EVENTLOG_ERROR_TYPE, 0, msg );
        return;
    }
 
    // number of image encoders
    UINT num = 0;
 
    // size of the image encoder array in bytes
    UINT size = 0;
 
    GetImageEncodersSize( &num, &size );
    if ( size == 0 ){
        logMessage( EVENTLOG_ERROR_TYPE, 0, LIB_NAME L": failed to get Image Encorders.\n" );
        return;
    }
 
    ImageCodecInfo *pImageCodecInfo = (ImageCodecInfo*)(malloc( size ));
    if (pImageCodecInfo == NULL){
        logMessage( EVENTLOG_ERROR_TYPE, 0, LIB_NAME L": failed to malloc Image Encorders.\n" );
        return;
    }
 
    GetImageEncoders( num, size, pImageCodecInfo );
 
    ImageEncorders = ImageEncorderMap();
    for(UINT i=0; i<num; ++i){
        wstring wsExtensionList = pImageCodecInfo[i].FilenameExtension;
        wstring::size_type nStart = 0;
        while( (nStart=wsExtensionList.find(L".", nStart)) != -1 ){
            wstring::size_type nEnd = wsExtensionList.find( L";", nStart );
            wstring wsExtensionOne = wsExtensionList.substr( nStart+1, nEnd-nStart-1 );
            ImageEncorders[ wsExtensionOne ] = pImageCodecInfo[i].Clsid;
            nStart = nEnd;
        }
    }
 
    // PixelFormat1bppIndexed で SetPixel が成功するかどうか確認
    Bitmap bmpTrial( 1, 1, PixelFormat1bppIndexed );
    bCanBW = ( bmpTrial.SetPixel( 0, 0, Color( 0xff000000 ) ) == Ok );
}
 
GdiHelper::~GdiHelper()
{
    if ( gdiToken != NULL ){
        GdiplusShutdown( gdiToken );
    }
}
 
bool GdiHelper::GetEncoderClsIdByExt(
    const wchar_t *wsExtension,
    CLSID* pClsid
)
{
    wchar_t    wsExtLocal[ MAX_PATH ];
 
    wcscpy_s( wsExtLocal, wsExtension );
    _wcsupr_s( wsExtLocal );
 
    ImageEncorderMap::iterator iter = ImageEncorders.find( wsExtLocal );
    if ( iter != ImageEncorders.end() ){
        *pClsid = iter->second;
        return true;
    } else {
        return false;
    }
}
 
bool GdiHelper::saveMatrix(
    const wchar_t *fileName, 
    const wchar_t *fileExt, 
    MATRIX matrix,
    int size
)
{
    Color colBack  = Color( 0xffffffff );
    Color colFront = Color( 0xff000000 );
    Status stat;
 
    Bitmap *bmpWork = new Bitmap( size, size, 
        ( bCanBW )
            ? PixelFormat1bppIndexed    // Win7(GDI+ 6.x)
            : PixelFormat32bppARGB        // Vista(GDI+ 5.x)
    );
 
    if ( bCanBW ){
        int nPalletSize = bmpWork->GetPaletteSize();
        ColorPalette *pPalette = (ColorPalette*)malloc( nPalletSize );
        bmpWork->GetPalette( pPalette, nPalletSize );
        pPalette->Entries[0] = colBack.GetValue();
        pPalette->Entries[1] = colFront.GetValue();
        bmpWork->SetPalette( pPalette );
        free( pPalette );
    }
 
    // 背景消去
    Graphics gWork( bmpWork );
    SolidBrush *brshBack = new SolidBrush( colBack );
    gWork.FillRectangle( brshBack, 0, 0, size, size );
    delete brshBack;
 
    // ドット描画
    for ( int y = 0; y < size && y < MAX_MATRIX_SIZE; ++y ){
        for ( int x = 0; x < size && x < MAX_MATRIX_SIZE; ++x ){
            if ( matrix[y][x] ){
                bmpWork->SetPixel( x, y, colFront );
            }
        }
    }
 
    CLSID    clsid;
    if ( GetEncoderClsIdByExt( fileExt, &clsid ) ){
        stat = bmpWork->Save( fileName, &clsid, NULL );
        if (stat != Ok){
            wchar_t msg[64] = L"";
            wsprintf( msg, LIB_NAME L": failed to save the image. <%d> [%s]\n", stat, GDIStatus[ stat ] );
            logMessage( EVENTLOG_ERROR_TYPE, 0, msg );
        }
    }
 
    delete bmpWork;
 
    return (stat == Ok);
}
 
}
 
// EOF

EventLogger.h

すべてを展開すべてを収束
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
#pragma once
 
//#ifdef EVENT_LOGGER_EXPORTS
#ifdef GDIHELPER_EXPORTS
    #define EXPORT_EVLOG_SYMBOL __declspec(dllexport)
#else
    #define EXPORT_EVLOG_SYMBOL __declspec(dllimport)
#endif
 
#include <windows.h>
 
/**
	EventLog にメッセージを登録します。
 
	@attention	ログの登録先、イベントソース、イベントIDは固定です。
		<table>
		<tr><th>登録先</th><td>Windows ログ/アプリケーション</td></tr>
		<tr><th>ソース</th><td>WSH</td></tr>
		<tr><th>イベントID</th><td>0</td></tr>
		</table>
*/
EXPORT_EVLOG_SYMBOL void logMessage(
    WORD    wType,        ///< イベントの種類
    WORD    wCategory,    ///< イベントの分類
    LPCWSTR    lpMsg,        ///< メッセージ
    LPCWSTR    lpUNCServerName = NULL    ///< 操作を実行するサーバーの名前。省略時は localhost。
);
 
// EOF

EventLogger.cpp

すべてを展開すべてを収束
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 
 
 
 
 
 
 
 
 
 
 
 
 
 
-
-
|
|
|
|
|
|
!
!
 
 
#include "stdafx.h"
 
#define    EVENT_LOGGER_EXPORTS    (1)
#include "EventLogger.h"
 
#define    EVENT_SOURCE_NAME    L"WSH"
#define    WSH_EVENT_ID        (0)
 
EXPORT_EVLOG_SYMBOL void logMessage(
    WORD    wType,
    WORD    wCategory,
    LPCWSTR    lpMsg,
    LPCWSTR    lpUNCServerName
)
{
    if ( HANDLE hEvSrc = RegisterEventSource( lpUNCServerName, EVENT_SOURCE_NAME ) ){
        LPCWSTR lpStrings[] = { lpMsg };
        ReportEvent( 
            hEvSrc, wType, wCategory, WSH_EVENT_ID, NULL, 
            _countof(lpStrings), 0, lpStrings, NULL 
        );
        DeregisterEventSource( hEvSrc );
    }
}
 
// EOF

Tester.cpp

すべてを展開すべてを収束
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
-
|
!
 
 
-
|
|
|
|
|
|
|
|
-
|
|
|
|
|
|
|
|
!
|
-
|
|
|
!
|
|
|
|
|
|
!
// Tester.cpp : コンソール アプリケーションのエントリ ポイントを定義します。
//
 
#include "stdafx.h"
#include <locale.h>
#include <string>
#include "../GdiHelper/GdiHelper.h"
#include "../GdiHelper/EventLogger.h"
 
using namespace std;
 
#pragma comment(lib, "GdiHelper.lib")
 
#define    LIB_NAME    L"Tester"
 
/// 保存する拡張子
wchar_t    *Exts[] = {
    L"bmp", L"gif", L"jpg", L"png", L"tif", 
};
 
int _tmain(int argc, _TCHAR* argv[])
{
    wchar_t wszLocale[MAX_PATH];
    GetLocaleInfoW( GetThreadLocale(), LOCALE_SABBREVLANGNAME, wszLocale, _countof(wszLocale));
    _wsetlocale( LC_ALL, wszLocale );
 
//	logMessage( EVENTLOG_INFORMATION_TYPE, 0, LIB_NAME L": Start\n" );
 
    TakeAsh::GdiHelper *helper = new TakeAsh::GdiHelper();
 
    TakeAsh::GdiHelper::MATRIX matrix ={
        { 0,0,0,0,0,0,0,0, },
        { 1,1,1,1,1,0,0,0, },
        { 0,0,1,0,1,0,1,0, },
        { 0,0,1,0,1,0,1,0, },
        { 0,0,1,0,1,1,0,0, },
        { 0,0,1,0,1,1,1,0, },
        { 0,0,1,0,1,0,1,0, },
        { 0,0,1,0,1,0,1,0, },
    };
 
    for( int i=0; i<_countof(Exts); ++i ){
        wstring path = L"../_Output/Test01.";
        path.append( Exts[i] );
        helper->saveMatrix( path.c_str(), Exts[i], matrix, 8 );
    }
 
    delete helper;
 
//	logMessage( EVENTLOG_INFORMATION_TYPE, 0, LIB_NAME L": Exit\n" );
 
    return 0;
}

リロード   新規 下位ページ作成 編集 凍結 差分 添付 コピー 名前変更   ホーム 一覧 検索 最終更新 バックアップ リンク元   ヘルプ   最終更新のRSS
Last-modified: Mon, 04 Mar 2013 23:07:00 JST (1995d)