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 "__filterMask"
// and it must support member function "response" 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:ixelFormat 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(&rect, Gdiplus::ImageLockModeWrite, pixelFormat, &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 "m*n" 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(&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>& 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
请熟悉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 "__filterMask"
// and it must support member function "response" 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:ixelFormat 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(&rect, Gdiplus::ImageLockModeWrite, pixelFormat, &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 "m*n" 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(&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>& 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