显式加载dll

动态链接库有显式加载和隐式两种方式,隐式加载比较常见,本文介绍显示加载的方法。

头文件不需要任何写什么,直接写需要导出的函数

例如

//MyImageProcess.h
#define  LINEWIDTH(bits)  (((bits) + 31) / 32 * 4)

extern"C" void __declspec(dllexport)  WELLNER_MODIFYED(LPBYTE lpSrc, LPBYTE lpDst, LPBYTE lpDst_, int nSrcCount, int nW, int nH);
extern"C" void __declspec(dllexport)  ADJUST_BRIGHT_CONTRAST(LPBYTE lpSrc, LPBYTE lpDst, int nSrcCount, int nW, int nH);


然后源文件

// MyImageProcess.cpp : 定义 DLL 应用程序的导出函数。
#include "stdafx.h"
#include "MyImageProcess.h"
#include"malloc.h"


void WELLNER_MODIFYED(LPBYTE lpSrc, LPBYTE lpDst, LPBYTE lpDst_, int nSrcCount, int nW, int nH)
{

	int nSrcLine = LINEWIDTH(nW*nSrcCount);
	int nR, nG, nB;


	for (int i = 0; i < nH; i++)
	{
		for (int j = 0; j < nW; j++)
		{
			nR = lpSrc[i*nSrcLine + j * 3];
			nG = lpSrc[i*nSrcLine + j * 3 + 1];
			nB = lpSrc[i*nSrcLine + j * 3 + 2];
			lpDst_[i*nW + j] = BYTE(nR*0.3 + nG*0.5 + nB*0.2);
		}
	}
	int S = nW >> 3;
	int T = 15;
	unsigned long* integralImg = 0;

	int i, j;

	long sum = 0;

	int count = 0;

	int index;

	int x1, y1, x2, y2;

	int s2 = S / 2;

	// create the integral image   

	integralImg = (unsigned long*)malloc(nW*nH*sizeof(unsigned long*));

	for (i = 0; i < nW; i++)

	{
		// reset this column sum   

		sum = 0;

		for (j = 0; j < nH; j++)

		{

			index = j*nW + i;

			sum += lpDst_[index];

			if (i == 0)

				integralImg[index] = sum;

			else

				integralImg[index] = integralImg[index - 1] + sum;

		}

	}

	// perform thresholding   

	for (i = 0; i < nW; i++)

	{

		for (j = 0; j < nH; j++)

		{

			index = j*nW + i;

			// set the SxS region   

			x1 = i - s2; x2 = i + s2;

			y1 = j - s2; y2 = j + s2;

			// check the border   

			if (x1 < 0) x1 = 0;

			if (x2 >= nW) x2 = nW - 1;

			if (y1 < 0) y1 = 0;

			if (y2 >= nH) y2 = nH - 1;

			count = (x2 - x1)*(y2 - y1);

			// I(x,y)=s(x2,y2)-s(x1,y2)-s(x2,y1)+s(x1,x1)   

			sum = integralImg[y2*nW + x2] -

				integralImg[y1*nW + x2] -

				integralImg[y2*nW + x1] +

				integralImg[y1*nW + x1];

			if ((long)(lpDst_[index] * count) < (long)(sum*(100 - T) / 100))

				lpDst[index] = 0;

			else

				lpDst[index] = 255;

		}

	}

	free(integralImg);
}

void ADJUST_BRIGHT_CONTRAST(LPBYTE lpSrc, LPBYTE lpDst, int nSrcCount, int nW, int nH)
{

	int nSrcLine = LINEWIDTH(nW*nSrcCount);
	float contrast = 1.5f; // default value;
	float brightness = 1.0f; // default value;
	// calculate RED, GREEN, BLUE means of pixel
	int index = 0;
	int rgbmeans[3] = { 0, 0, 0 };
	double redSum = 0, greenSum = 0, blueSum = 0;
	double total = nH * nW;
	for (int i = 0; i < nH; i++)
	{
		int ta = 0, tr = 0, tg = 0, tb = 0;
		for (int j = 0; j < nW; j++) {
			//index = i * nW + j;
			/*ta = (inPixels[index] >> 24) & 0xff;
			tr = (inPixels[index] >> 16) & 0xff;
			tg = (inPixels[index] >> 8) & 0xff;
			tb = inPixels[index] & 0xff;*/
			tr = lpSrc[i*nSrcLine + j * 3];
			tg = lpSrc[i*nSrcLine + j * 3 + 1];
			tb = lpSrc[i*nSrcLine + j * 3 + 2];
			redSum += tr;
			greenSum += tg;
			blueSum += tb;
		}
	}
	rgbmeans[0] = (int)(redSum / total);
	rgbmeans[1] = (int)(greenSum / total);
	rgbmeans[2] = (int)(blueSum / total);
	// adjust contrast and brightness algorithm, here
	for (int i = 0; i < nH; i++) {
		int ta = 0, tr = 0, tg = 0, tb = 0;
		for (int j = 0; j < nW; j++) {
			//index = i * nW + j;
			/*ta = (inPixels[index] >> 24) & 0xff;
			tr = (inPixels[index] >> 16) & 0xff;
			tg = (inPixels[index] >> 8) & 0xff;
			tb = inPixels[index] & 0xff;*/
			tr = lpSrc[i*nSrcLine + j * 3];
			tg = lpSrc[i*nSrcLine + j * 3 + 1];
			tb = lpSrc[i*nSrcLine + j * 3 + 2];
			// remove means
			tr -= rgbmeans[0];
			tg -= rgbmeans[1];
			tb -= rgbmeans[2];
			// adjust contrast now !!!
			tr = (int)(tr * contrast);
			tg = (int)(tg * contrast);
			tb = (int)(tb * contrast);
			// adjust brightness
			tr += (int)(rgbmeans[0] * brightness);
			tg += (int)(rgbmeans[1] * brightness);
			tb += (int)(rgbmeans[2] * brightness);
			//outPixels[index] = (ta << 24) | (clamp(tr) << 16) | (clamp(tg) << 8) | clamp(tb);
			tr = tr > 255 ? 255 : (tr < 0 ? 0 : tr);
			tg = tg > 255 ? 255 : (tg < 0 ? 0 : tg);
			tb = tb > 255 ? 255 : (tb < 0 ? 0 : tb);
			lpDst[i*nSrcLine + j * 3] = tr;
			lpDst[i*nSrcLine + j * 3 + 1] = tg;
			lpDst[i*nSrcLine + j * 3 + 2] = tb;
		}
	}
}

最后在调用的地方写这样的代码

typedef void(*AddProc1)(LPBYTE lpSrc, LPBYTE lpDst, LPBYTE lpDst_, int nSrcCount, int nW, int nH);//定义函数指针类型

	HINSTANCE hInst;
	AddProc1 Add1 = NULL;
	hInst = LoadLibrary("MyImageProcess.dll");//动态加载Dll
	if (hInst != NULL)
	{
		Add1 = (AddProc1)GetProcAddress(hInst, "WELLNER_MODIFYED");//获取Dll的导出函数

		if (!Add1)
		{
			MessageBox("获取Add函数地址失败!");
		}
		Add1(lpSrcBit, lpDstBit, lpDst_Bit, nCount, nW, nH);

		//显示图像数据
		m_DstView.SetImgData(lpDstBit, nW, nH, nDstCount);
		m_DstView.Invalidate();

		delete[] lpSrcBit;
		delete[] lpDstBit;
		delete[]lpDst_Bit;
		FreeLibrary(hInst);
	}
AddProc1、Add1这些名字随便起,没关系。OK,这样就可以调用了。

版权声明:

posted on 2014-12-10 16:30  moffis  阅读(220)  评论(0编辑  收藏  举报

导航