请熟悉VC++的朋友帮忙翻译一小段代码 ( 积分: 6 )

W

whoawho

Unregistered / Unconfirmed
GUEST, unregistred user!
后面附上的是一段VC代码,头文件是用来实现GDI+图像滤波的,有一个小小的演示代码。
请熟悉VC的朋友帮忙翻译成Delphi,我的VC刚学习,实在看得头晕,救命!
头文件:
=====================================
// Author: newsuppy
// E-mail: newsuppy@msn.com
// Date: Nov. 1, 2004
// Version: v0.1.0 (it include in newsuppy's image process toolkit)
// Declaration: You can copy&rewirte the code yourself, but please put me in your acknowledgments
// File: spatialFilter.h

#ifndef SPATIALFILTER_H
#define SPATIALFILTER_H

#include <vector>
#include <numeric>
#include <algorithm>
#include <gdiplus.h>

namespace nsimgtk
{
// function: filter a width*height rectangle portion of a bitmap one pixel by one pixel with the filterMask
// template parameter:
// pixelType: pixel's type depend on pixelFormat
// pixelFormat: pixel's format, but this function doesn't support all the PixelFormat define in Gdiplus
// | supported PixelFormat | pixel type |
// 1, PixelFormat8bppIndexed ----------------------- unsigned char(8bit)
// 2, PixelFormat16bppARGB1555 ---------------- unsigned short int(16bit)
// 3, PixelFormat16bppGrayScale ---------------- unsigned short int(16bit)
// 4, PixelFormat16bppRGB555 ---------------- unsigned short int(16bit)
// 5, PixelFormat16bppRGB565 ---------------- unsigned short int(16bit)
// 6, PixelFormat32bppARGB ----------------- unsigned int(32bit)
// 6, PixelFormat32bppPARGB ----------------- unsigned int(32bit)
// 6, PixelFormat32bppRGB ----------------- unsigned int(32bit)
// FilterMask: FilterMask is a functor, it should inherit class &quot;__filterMask&quot;
// and it must support member function &quot;response&quot; like this:
// pixelType::FilterMask response();
// function parameter:
// p_bitmap: a pointer to Gdiplus::Bitmap class
// filterMask: the filterMask's instance
// x, y, width, height: they are the parameters of the rectangle which should be process
// (x,y) are the left-up point of the rectangle
// return value: if failed,return false; else if success, return true;
template <typename pixelType, Gdiplus::pixelFormat pixelFormat, class FilterMask>
bool SpatialFilterAlgo(Gdiplus::Bitmap* const p_bitmap, FilterMask filterMask, unsigned int x, unsigned int y,
unsigned int width, unsigned int height)
{
if (p_bitmap == NULL)
{
return false;
}

if ((width + x > p_bitmap->GetWidth()) || (height + y >p_bitmap->GetHeight()))
{
return false;
}

Gdiplus::BitmapData bitmapData;
Gdiplus::Rect rect(x, y, width,height);

if (p_bitmap->LockBits(&amp;rect, Gdiplus::ImageLockModeWrite, pixelFormat, &amp;bitmapData) != Gdiplus::Ok)
{
return false;
}

pixelType *pixels = (pixelType*)bitmapData.Scan0;

const unsigned int m = filterMask.d_m; // mask's width
const unsigned int n = filterMask.d_n; // mask's height
std::vector<pixelType> tmpImage((m-1+width)*(n-1+height)); // extend image to use zero-padding

// copy original bitmap to extended image with zero-padding method
for (unsigned int row=0; row<height; ++row)
{
for (unsigned int col=0; col<width; ++col)
{
tmpImage[(col+m/2)+(row+n/2)*(bitmapData.Stride/sizeof(pixelType)+m-1)] =
pixels[col+row*bitmapData.Stride/sizeof(pixelType)];
}
}

// process every pixel with filterMask
for (unsigned int row=0; row<height; ++row)
{
for (unsigned int col=0; col<width; ++col)
{
// fill the &quot;m*n&quot; mask with the current pixel's neighborhood
for (unsigned int i=0; i<n; ++i)
{
for (unsigned int j=0; j<m; ++j)
{
filterMask.d_mask[i*m+j] = tmpImage[(col+j)+(row+i)*(bitmapData.Stride/sizeof(pixelType)+m-1)];
}
}

// replace the current pixel with filter mask's response
pixels[col+row*bitmapData.Stride/sizeof(pixelType)] = filterMask.response();
}
}

if (p_bitmap->UnlockBits(&amp;bitmapData) != Gdiplus::Ok)
{
return false;
}

return true;
}

// base class for filterMask, be only used for the library
// others filterMask should inherit it
template <typename pixelType>
struct __filterMask
{
const unsigned int d_m;
const unsigned int d_n;

std::vector<pixelType> d_mask;

// filter mask's width and heigh must be a odd, if not, it will plus one for the width or the height
__filterMask(unsigned int m, unsigned int n)
: d_m(m%2 ? m:m+1), d_n(n%2 ? n:n+1), d_mask(d_m*d_n)
{
}
};

// special averaging(smoothing) filter mask, its' weights are all 1
template <typename pixelType>
class averagingFilterMaskSp
: public __filterMask<pixelType>
{
public:
averagingFilterMaskSp(unsigned int m, unsigned int n)
: __filterMask<pixelType>(m, n)
{ }

pixelType response()
{
return std::accumulate(d_mask.begin(), d_mask.end(), 0) / (d_m * d_n);
}
};

// averaging(smoothing) filter mask
template <typename pixelType>
class averagingFilterMask
: public __filterMask<pixelType>
{
private:
std::vector<pixelType> d_weight; // weights' vector(m*n)
int d_weight_sum; // all weights' sum

public:
averagingFilterMask(unsigned int m, unsigned int n, const std::vector<pixelType>&amp; weightVec)
: __filterMask<pixelType>(m, n), d_weight(weightVec)
{
if (weightVec.size() != d_mask.size())
{
// if weight's size isn't equal to mask's size, it will change filter mask as a special filter mask
d_weight.resize(d_mask.size(), 1);
}

d_weight_sum = std::accumulate(d_weight.begin(), d_weight.end(), 0);
}

pixelType response()
{
return std::inner_product(d_mask.begin(), d_mask.end(), d_weight.begin(), 0) / d_weight_sum;
}
};

// median filter mask
template <typename pixelType>
class medianFilterMask
: public __filterMask<pixelType>
{
public:
medianFilterMask(unsigned int m, unsigned int n)
: __filterMask<pixelType>(m, n)
{ }

pixelType response()
{
std::sort(d_mask.begin(), d_mask.end());
return d_mask[d_mask.size()/2];
}
};
}

#endif
 
W

whoawho

Unregistered / Unconfirmed
GUEST, unregistred user!
后面附上的是一段VC代码,头文件是用来实现GDI+图像滤波的,有一个小小的演示代码。
请熟悉VC的朋友帮忙翻译成Delphi,我的VC刚学习,实在看得头晕,救命!
头文件:
=====================================
// Author: newsuppy
// E-mail: newsuppy@msn.com
// Date: Nov. 1, 2004
// Version: v0.1.0 (it include in newsuppy's image process toolkit)
// Declaration: You can copy&amp;rewirte the code yourself, but please put me in your acknowledgments
// File: spatialFilter.h

#ifndef SPATIALFILTER_H
#define SPATIALFILTER_H

#include <vector>
#include <numeric>
#include <algorithm>
#include <gdiplus.h>

namespace nsimgtk
{
// function: filter a width*height rectangle portion of a bitmap one pixel by one pixel with the filterMask
// template parameter:
// pixelType: pixel's type depend on pixelFormat
// pixelFormat: pixel's format, but this function doesn't support all the PixelFormat define in Gdiplus
// | supported PixelFormat | pixel type |
// 1, PixelFormat8bppIndexed ----------------------- unsigned char(8bit)
// 2, PixelFormat16bppARGB1555 ---------------- unsigned short int(16bit)
// 3, PixelFormat16bppGrayScale ---------------- unsigned short int(16bit)
// 4, PixelFormat16bppRGB555 ---------------- unsigned short int(16bit)
// 5, PixelFormat16bppRGB565 ---------------- unsigned short int(16bit)
// 6, PixelFormat32bppARGB ----------------- unsigned int(32bit)
// 6, PixelFormat32bppPARGB ----------------- unsigned int(32bit)
// 6, PixelFormat32bppRGB ----------------- unsigned int(32bit)
// FilterMask: FilterMask is a functor, it should inherit class &quot;__filterMask&quot;
// and it must support member function &quot;response&quot; like this:
// pixelType::FilterMask response();
// function parameter:
// p_bitmap: a pointer to Gdiplus::Bitmap class
// filterMask: the filterMask's instance
// x, y, width, height: they are the parameters of the rectangle which should be process
// (x,y) are the left-up point of the rectangle
// return value: if failed,return false; else if success, return true;
template <typename pixelType, Gdiplus::pixelFormat pixelFormat, class FilterMask>
bool SpatialFilterAlgo(Gdiplus::Bitmap* const p_bitmap, FilterMask filterMask, unsigned int x, unsigned int y,
unsigned int width, unsigned int height)
{
if (p_bitmap == NULL)
{
return false;
}

if ((width + x > p_bitmap->GetWidth()) || (height + y >p_bitmap->GetHeight()))
{
return false;
}

Gdiplus::BitmapData bitmapData;
Gdiplus::Rect rect(x, y, width,height);

if (p_bitmap->LockBits(&amp;rect, Gdiplus::ImageLockModeWrite, pixelFormat, &amp;bitmapData) != Gdiplus::Ok)
{
return false;
}

pixelType *pixels = (pixelType*)bitmapData.Scan0;

const unsigned int m = filterMask.d_m; // mask's width
const unsigned int n = filterMask.d_n; // mask's height
std::vector<pixelType> tmpImage((m-1+width)*(n-1+height)); // extend image to use zero-padding

// copy original bitmap to extended image with zero-padding method
for (unsigned int row=0; row<height; ++row)
{
for (unsigned int col=0; col<width; ++col)
{
tmpImage[(col+m/2)+(row+n/2)*(bitmapData.Stride/sizeof(pixelType)+m-1)] =
pixels[col+row*bitmapData.Stride/sizeof(pixelType)];
}
}

// process every pixel with filterMask
for (unsigned int row=0; row<height; ++row)
{
for (unsigned int col=0; col<width; ++col)
{
// fill the &quot;m*n&quot; mask with the current pixel's neighborhood
for (unsigned int i=0; i<n; ++i)
{
for (unsigned int j=0; j<m; ++j)
{
filterMask.d_mask[i*m+j] = tmpImage[(col+j)+(row+i)*(bitmapData.Stride/sizeof(pixelType)+m-1)];
}
}

// replace the current pixel with filter mask's response
pixels[col+row*bitmapData.Stride/sizeof(pixelType)] = filterMask.response();
}
}

if (p_bitmap->UnlockBits(&amp;bitmapData) != Gdiplus::Ok)
{
return false;
}

return true;
}

// base class for filterMask, be only used for the library
// others filterMask should inherit it
template <typename pixelType>
struct __filterMask
{
const unsigned int d_m;
const unsigned int d_n;

std::vector<pixelType> d_mask;

// filter mask's width and heigh must be a odd, if not, it will plus one for the width or the height
__filterMask(unsigned int m, unsigned int n)
: d_m(m%2 ? m:m+1), d_n(n%2 ? n:n+1), d_mask(d_m*d_n)
{
}
};

// special averaging(smoothing) filter mask, its' weights are all 1
template <typename pixelType>
class averagingFilterMaskSp
: public __filterMask<pixelType>
{
public:
averagingFilterMaskSp(unsigned int m, unsigned int n)
: __filterMask<pixelType>(m, n)
{ }

pixelType response()
{
return std::accumulate(d_mask.begin(), d_mask.end(), 0) / (d_m * d_n);
}
};

// averaging(smoothing) filter mask
template <typename pixelType>
class averagingFilterMask
: public __filterMask<pixelType>
{
private:
std::vector<pixelType> d_weight; // weights' vector(m*n)
int d_weight_sum; // all weights' sum

public:
averagingFilterMask(unsigned int m, unsigned int n, const std::vector<pixelType>&amp; weightVec)
: __filterMask<pixelType>(m, n), d_weight(weightVec)
{
if (weightVec.size() != d_mask.size())
{
// if weight's size isn't equal to mask's size, it will change filter mask as a special filter mask
d_weight.resize(d_mask.size(), 1);
}

d_weight_sum = std::accumulate(d_weight.begin(), d_weight.end(), 0);
}

pixelType response()
{
return std::inner_product(d_mask.begin(), d_mask.end(), d_weight.begin(), 0) / d_weight_sum;
}
};

// median filter mask
template <typename pixelType>
class medianFilterMask
: public __filterMask<pixelType>
{
public:
medianFilterMask(unsigned int m, unsigned int n)
: __filterMask<pixelType>(m, n)
{ }

pixelType response()
{
std::sort(d_mask.begin(), d_mask.end());
return d_mask[d_mask.size()/2];
}
};
}

#endif
 
W

whoawho

Unregistered / Unconfirmed
GUEST, unregistred user!
运行该程序需要GDI+的支持,Windows XP/2003 Server可以直接运行,因为
已经包括了gdiplus.dll,而Windows 2000则需先下载这个组件,在microsoft网站上。
如果你安装了Office 2003等软件同样会包括该组件。
 
W

whoawho

Unregistered / Unconfirmed
GUEST, unregistred user!
演示用小程序:
=========================================
#define UNICODE
#define _UNICODE
#include <windows.h>
#include <gdiplus.h>
#include &quot;spatialFilter.h&quot;
using namespace Gdiplus;
using namespace nsimgtk;

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

Gdiplus::ImageCodecInfo* pImageCodecInfo = NULL;

Gdiplus::GetImageEncodersSize(&amp;num, &amp;size);
if(size == 0)
return -1; // Failure

pImageCodecInfo = (Gdiplus::ImageCodecInfo*)(malloc(size));
if(pImageCodecInfo == NULL)
return -1; // Failure

Gdiplus::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
}

VOID OnPaint(HDC hdc)
{
Graphics graphics(hdc);

// Averaging filtering(3x3 mask, all values are 1 in weight)
Bitmap bitmapWith3x3MaskSp(L&quot;image/Fig3.35(a).jpg&quot;);
graphics.DrawImage(&amp;bitmapWith3x3MaskSp, 10, 10,bitmapWith3x3MaskSp.GetWidth()/2,bitmapWith3x3MaskSp.GetHeight()/2);
averagingFilterMaskSp<unsigned char> avgfilterMaskSp3x3(3,3);
if (SpatialFilterAlgo<unsigned char,PixelFormat8bppIndexed>(&amp;bitmapWith3x3MaskSp,
avgfilterMaskSp3x3, 0, 0, bitmapWith3x3MaskSp.GetWidth(), bitmapWith3x3MaskSp.GetHeight())==false)
{
MessageBox(NULL,L&quot;No change&quot;,L&quot;No change&quot;,MB_OK);
return;
}
graphics.DrawImage(&amp;bitmapWith3x3MaskSp,
15+bitmapWith3x3MaskSp.GetWidth()/2, 10,bitmapWith3x3MaskSp.GetWidth()/2,bitmapWith3x3MaskSp.GetHeight()/2);

// Averaging filtering(9x9 mask, all values are 1 in weight)
Bitmap bitmapWith9x9MaskSp(L&quot;image/Fig3.35(a).jpg&quot;);
averagingFilterMaskSp<unsigned char> avgfilterMaskSp9x9(9,9);
if (SpatialFilterAlgo<unsigned char,PixelFormat8bppIndexed>(&amp;bitmapWith9x9MaskSp,
avgfilterMaskSp9x9, 0, 0, bitmapWith9x9MaskSp.GetWidth(), bitmapWith9x9MaskSp.GetHeight())==false)
{
MessageBox(NULL,L&quot;No change&quot;,L&quot;No change&quot;,MB_OK);
return;
}
graphics.DrawImage(&amp;bitmapWith9x9MaskSp,
20+bitmapWith9x9MaskSp.GetWidth(), 10,bitmapWith9x9MaskSp.GetWidth()/2,bitmapWith9x9MaskSp.GetHeight()/2);

// Averaging filtering(3x3 mask, weight are user-defined)
Bitmap bitmapWith3x3Mask(L&quot;image/Fig3.35(a).jpg&quot;);
std::vector<unsigned char> weight(9);
weight[0] = 1, weight[1] = 2, weight[2] = 1,
weight[0] = 2, weight[1] = 4, weight[2] = 2,
weight[0] = 1, weight[1] = 2, weight[2] = 1;
averagingFilterMask<unsigned char> avgfilterMask3x3(3,3,weight);
if (SpatialFilterAlgo<unsigned char,PixelFormat8bppIndexed>(&amp;bitmapWith3x3Mask,
avgfilterMask3x3, 0, 0, bitmapWith3x3Mask.GetWidth(), bitmapWith3x3Mask.GetHeight())==false)
{
MessageBox(NULL,L&quot;No change&quot;,L&quot;No change&quot;,MB_OK);
return;
}
graphics.DrawImage(&amp;bitmapWith3x3Mask,
20+bitmapWith3x3Mask.GetWidth()*1.5, 10,bitmapWith3x3Mask.GetWidth()/2,bitmapWith3x3Mask.GetHeight()/2);


// Median filtering(3x3 mask)
Bitmap bitmapWithMedianFilter(L&quot;image/Fig3.37(a).jpg&quot;);
graphics.DrawImage(&amp;bitmapWithMedianFilter, 10, 80+bitmapWith3x3Mask.GetHeight()/2,
bitmapWithMedianFilter.GetWidth()/1.5,bitmapWithMedianFilter.GetHeight()/1.5);
medianFilterMask<unsigned char> medianfilterMask3x3(3,3);
if (SpatialFilterAlgo<unsigned char,PixelFormat8bppIndexed>(&amp;bitmapWithMedianFilter,
medianfilterMask3x3, 0, 0, bitmapWithMedianFilter.GetWidth(), bitmapWithMedianFilter.GetHeight())==false)
{
MessageBox(NULL,L&quot;No change&quot;,L&quot;No change&quot;,MB_OK);
return;
}
graphics.DrawImage(&amp;bitmapWithMedianFilter,(REAL)(15+bitmapWithMedianFilter.GetWidth()/1.5),
80+bitmapWith3x3Mask.GetHeight()/2,bitmapWithMedianFilter.GetWidth()/1.5,bitmapWithMedianFilter.GetHeight()/1.5);

CLSID imgClsid;
GetEncoderClsid(L&quot;image/jpeg&quot;, &amp;imgClsid);
bitmapWith3x3MaskSp.Save(L&quot;image/Fig3.35(b).jpg&quot;, &amp;imgClsid, NULL);
bitmapWith9x9MaskSp.Save(L&quot;image/Fig3.35(c).jpg&quot;, &amp;imgClsid, NULL);
bitmapWith3x3Mask.Save(L&quot;image/Fig3.35(d).jpg&quot;, &amp;imgClsid, NULL);
bitmapWithMedianFilter.Save(L&quot;image/Fig3.37(b).jpg&quot;, &amp;imgClsid, NULL);
}

LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);

INT WINAPI WinMain(HINSTANCE hInstance, HINSTANCE, PSTR, INT iCmdShow)
{
HWND hWnd;
MSG msg;
WNDCLASS wndClass;
GdiplusStartupInput gdiplusStartupInput;
ULONG_PTR gdiplusToken;

// Initialize GDI+.
GdiplusStartup(&amp;gdiplusToken, &amp;gdiplusStartupInput, NULL);

wndClass.style = CS_HREDRAW | CS_VREDRAW;
wndClass.lpfnWndProc = WndProc;
wndClass.cbClsExtra = 0;
wndClass.cbWndExtra = 0;
wndClass.hInstance = hInstance;
wndClass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wndClass.hCursor = LoadCursor(NULL, IDC_ARROW);
wndClass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
wndClass.lpszMenuName = NULL;
wndClass.lpszClassName = TEXT(&quot;GettingStarted&quot;);

RegisterClass(&amp;wndClass);

hWnd = CreateWindow(
TEXT(&quot;GettingStarted&quot;), // window class name
TEXT(&quot;Getting Started&quot;), // window caption
WS_OVERLAPPEDWINDOW, // window style
CW_USEDEFAULT, // initial x position
CW_USEDEFAULT, // initial y position
1024, // initial x size
768, // initial y size
NULL, // parent window handle
NULL, // window menu handle
hInstance, // program instance handle
NULL); // creation parameters

ShowWindow(hWnd, iCmdShow);
UpdateWindow(hWnd);

while(GetMessage(&amp;msg, NULL, 0, 0))
{
TranslateMessage(&amp;msg);
DispatchMessage(&amp;msg);
}

GdiplusShutdown(gdiplusToken);
return msg.wParam;
} // WinMain

LRESULT CALLBACK WndProc(HWND hWnd, UINT message,
WPARAM wParam, LPARAM lParam)
{
HDC hdc;
PAINTSTRUCT ps;

switch(message)
{
case WM_PAINT:
hdc = BeginPaint(hWnd, &amp;ps);
OnPaint(hdc);
EndPaint(hWnd, &amp;ps);
return 0;
case WM_DESTROY:
PostQuitMessage(0);
return 0;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
} // WndProc
 
W

whoawho

Unregistered / Unconfirmed
GUEST, unregistred user!
解决了,不用了:)
 
顶部