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
|
/*a command line image hack program*/
//M$ falsely defines sprintf as removed from C++ without this?
#define _CRT_SECURE_NO_WARNINGS
#include <string>
#include <windows.h>
#include <objidl.h>
#include <gdiplus.h>
#include <gdiplusgraphics.h>
#include <gdipluscolor.h>
#include "framework.h"
#include "png2.h"
using namespace Gdiplus;
#pragma comment (lib,"Gdiplus.lib")
#define MAX_LOADSTRING 100
HINSTANCE hInst; // current instance
WCHAR szTitle[MAX_LOADSTRING]; // The title bar text
WCHAR szWindowClass[MAX_LOADSTRING]; // the main window class name
HWND mhWnd;
// Forward declarations of functions included in this code module:
ATOM MyRegisterClass(HINSTANCE hInstance);
BOOL InitInstance(HINSTANCE, int);
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
INT_PTR CALLBACK About(HWND, UINT, WPARAM, LPARAM);
/// this incredible function is required to save the image file as a .png file.
///This is so convoluted M$ had to provide this code in their docs, else .save()
///is unusuable by mere mortals.
int GetEncoderClsid(const WCHAR* format, CLSID* pClsid)
{
UINT num = 0; // number of image encoders
UINT size = 0; // size of the image encoder array in bytes
ImageCodecInfo* pImageCodecInfo = NULL;
GetImageEncodersSize(&num, &size);
if (size == 0)
return -1; // Failure
pImageCodecInfo = (ImageCodecInfo*)(malloc(size));
if (pImageCodecInfo == NULL)
return -1; // Failure
GetImageEncoders(num, size, pImageCodecInfo);
for (UINT j = 0; j < num; ++j)
{
if (wcscmp(pImageCodecInfo[j].MimeType, format) == 0)
{
*pClsid = pImageCodecInfo[j].Clsid;
free(pImageCodecInfo);
return j; // Success
}
}
free(pImageCodecInfo);
return -1; // Failure
}
int APIENTRY wWinMain(_In_ HINSTANCE hInstance,
_In_opt_ HINSTANCE hPrevInstance,
_In_ LPWSTR lpCmdLine,
_In_ int nCmdShow)
{
///VS generated gibberish
LoadStringW(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
LoadStringW(hInstance, IDC_PNG2, szWindowClass, MAX_LOADSTRING);
MyRegisterClass(hInstance);
nCmdShow = false; ///hide the main window, it has no value.
InitInstance (hInstance, nCmdShow);
///---------------------------------------
///translate windows mess back to standard argc/argv interface
/// because this is a windowed program, use messagebox instead of cout to talk to users
int reqargs = 5;
LPWSTR* argv;
int argc{};
argv = CommandLineToArgvW(GetCommandLineW(), &argc);
if(argc < reqargs) ///not enough args check
{
//MessageBoxA(useless pointer, message, title, 0 means OK button)
MessageBoxA(0, "Too few arguments. Usage: filename R G B","",0 );
return 0;
}
///--------------------------------------------------------
std::string stati[] ///the gdi+ errors, FWIW
{"Ok","GenericError","InvalidParameter (file not found, wrong type?)","OutOfMemory","ObjectBusy",
"InsufficientBuffer","NotImplemented","Win32Error","WrongState","Aborted",
"FileNotFound","ValueOverflow","AccessDenied","UnknownImageFormat",
"FontFamilyNotFound","FontStyleNotFound","NotTrueTypeFont",
"UnsupportedGdiplusVersion","GdiplusNotInitialized","PropertyNotFound",
"PropertyNotSupported","ProfileNotFound"};
GpStatus gps{}; ///set up gdi+
GdiplusStartupInput forizzle;
ULONG_PTR token;
gps = GdiplusStartup(&token, &forizzle, nullptr);
if (gps) { MessageBoxA(0, stati[gps].c_str(), "GDI Start", 0); return 0; }
///load the image file.
Bitmap original(argv[1]);
gps = original.GetLastStatus();
if (gps) { MessageBoxA(0, stati[gps].c_str(), "Image Load", 0); return 0; }
///process image.
uint8_t Rin = std::wcstol(argv[2],0,10);
uint8_t Gin = std::wcstol(argv[3], 0, 10);
uint8_t Bin = std::wcstol(argv[4], 0, 10);
uint32_t w{ original.GetWidth()},h{ original.GetHeight()};
Gdiplus::BitmapData data;
Gdiplus::Rect sq(0, 0, w, h);
///extremely useful code showing how to get the RGBA byte data in a usable
///format.
original.LockBits(&sq,
Gdiplus::ImageLockModeWrite, PixelFormat32bppARGB, &data);
uint8_t * cp = (uint8_t*)(data.Scan0);
char adj = 13;
for (int i = 0; i < w * h * 4;)
{
i++;
if(cp[i] >= 128+adj)
cp[i] = cp[i] - adj;
else
if (cp[i] <= 128-adj )
cp[i] = cp[i] + adj;
else
cp[i] = 128;
i++;
if (cp[i] >= 128 + adj)
cp[i] = cp[i] - adj;
else
if (cp[i] <= 128 - adj)
cp[i] = cp[i] + adj;
else
cp[i] = 128;
i++;
if (cp[i] >= 128 + adj)
cp[i] = cp[i] - adj;
else
if (cp[i] <= 128 - adj)
cp[i] = cp[i] + adj;
else
cp[i] = 128;
i++;
}
original.UnlockBits(&data);
/// Save the image.
CLSID pngClsid;
int whatsthis = GetEncoderClsid(L"image/png", &pngClsid);
if(whatsthis == -1)
{ MessageBoxA(0, "png not supported?!", "", 0); return 0; }
///quick and dirty new file name.
std::wstring nuname = argv[1];
nuname.replace(nuname.find(L"."),10, L"_Trans.png");
gps = original.Save(nuname.c_str(), &pngClsid);
if (gps) { MessageBoxA(0, stati[gps].c_str(), "Save", 0); return 0; }
GdiplusShutdown(token);
return 0;
}
/// more windows generated nonsense.
ATOM MyRegisterClass(HINSTANCE hInstance)
{
WNDCLASSEXW wcex;
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_PNG2));
wcex.hCursor = LoadCursor(nullptr, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wcex.lpszMenuName = MAKEINTRESOURCEW(IDC_PNG2);
wcex.lpszClassName = szWindowClass;
wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));
return RegisterClassExW(&wcex);
}
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
hInst = hInstance; // Store instance handle in our global variable
HWND hWnd = CreateWindowW(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, nullptr, nullptr, hInstance, nullptr);
mhWnd = hWnd;
ShowWindow(hWnd, nCmdShow);
return TRUE;
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{ return 0;}
INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{ return (INT_PTR)FALSE; }
|