[C++] 图像处理

打算用FreeType获取字体像素,然后贴在一张图上
然后这个就是图像处理工具,只有复制和镜像,但足够了
(旋转缩放难倒我了)
使用完成后需要手动释放资源(干脆用智能指针它不香吗)

代码

#ifndef __IMAGE_PROCESSING_HPP__
#define __IMAGE_PROCESSING_HPP__
#include 

typedef unsigned int uint;
typedef unsigned char uchar;

typedef std::string ImageTooBigError;
typedef std::string ImageSizeIsZeroError;
typedef std::string CannotCreateImageError;
typedef std::string ImageIsNullError;

const uint IMAGE_PIXELS_MAX = 4096;
const uint IMAGE_PIXEL_SIZE = 3;//RGB

struct Pixel
{
	uchar r = 0;
	uchar g = 0;
	uchar b = 0;
};

bool isPixelEqual(Pixel a, Pixel b)
{
	return (a.r == b.r) && (a.g == b.g) && (a.b == b.b);
}

struct Rect
{
	int x;
	int y;
	uint w;
	uint h;
};

struct Image
{
	uint width = 0;
	uint height = 0;
	Pixel* pixels = nullptr;
};

Image createImage(uint width, uint height)
{
	if (width > IMAGE_PIXELS_MAX) throw ImageTooBigError("Width is too big");
	if (height > IMAGE_PIXELS_MAX) throw ImageTooBigError("Height is too big");
	if (width == 0) throw ImageSizeIsZeroError("Width is zero");
	if (height == 0) throw ImageSizeIsZeroError("Height is zero");

	Image result;
	result.width = width;
	result.height = height;

	result.pixels = new Pixel[result.width * result.height];
	if (result.pixels == nullptr) throw CannotCreateImageError("Cannot create Image");

	return result;
}

void releaseImage(Image& image)
{
	image.width = 0;
	image.height = 0;

	if (image.pixels != nullptr)
	{
		delete[] image.pixels;
		image.pixels = nullptr;
	}
}

//Point to the same memory. 
void assignImage(Image& target, const Image& source)
{
	if (source.width == 0) throw ImageSizeIsZeroError("Width is zero");
	if (source.height == 0) throw ImageSizeIsZeroError("Height is zero");
	if (source.pixels == nullptr) throw ImageIsNullError("Source is null");

	target.width = source.width;
	target.height = source.height;

	if (target.pixels != nullptr)
	{
		delete[] target.pixels;
	}
	target.pixels = source.pixels;
}

//The pixels are the same, but point to different memory.
Image copyOutAnother(const Image& source)
{
	if (source.width == 0) throw ImageSizeIsZeroError("Width is zero");
	if (source.height == 0) throw ImageSizeIsZeroError("Height is zero");
	if (source.pixels == nullptr) throw ImageIsNullError("Source is null");

	Image result = createImage(source.width, source.height);

	for (uint i = 0; i < source.width * source.height; i++)
	{
		result.pixels[i] = source.pixels[i];
	}

	return result;
}

void copyToAnother(Image& target, const Image& source, int x = 0, int y = 0, Pixel* bg = nullptr)
{
	if (target.pixels == nullptr) throw ImageIsNullError("Traget is null");
	if (source.pixels == nullptr) throw ImageIsNullError("Source is null");
	if (x > (int)target.width || y > (int)target.height) return;

	for (uint i = 0; i + y < target.height; i++)
	{
		for (uint j = 0; j + x < target.width; j++)
		{
			Pixel pixel = source.pixels[i * source.width + j];
			if (bg != nullptr)
			{
				if (!isPixelEqual(pixel, *bg))
				{
					target.pixels[(i + y) * target.width + (j + x)] = pixel;
				}
			}
			else
			{
				target.pixels[(i + y) * target.width + (j + x)] = pixel;
			}
		}
	}
}

void copyToAnotherRect(Image& target, const Image& source, int x,int y,Rect rect, Pixel* bg = nullptr)
{
	if (target.pixels == nullptr) throw ImageIsNullError("Traget is null");
	if (source.pixels == nullptr) throw ImageIsNullError("Source is null");
	if (rect.x > (int)target.width || rect.y > (int)target.height) return;

	for (uint i = rect.y; (i + rect.y < target.height) && (i < rect.y + rect.h); i++)
	{
		for (uint j = rect.x; (j + rect.x < target.width) && (j < rect.x + rect.w); j++)
		{
			Pixel pixel = source.pixels[i * source.width + j];
			if (bg != nullptr)
			{
				if (!isPixelEqual(pixel, *bg))
				{
					target.pixels[(i + y) * target.width + (j + x)] = pixel;
				}
			}
			else
			{
				target.pixels[(i + y) * target.width + (j + x)] = pixel;
			}
		}
	}
}

void drawColor(Image& target, Pixel color)
{
	if (target.width == 0) throw ImageSizeIsZeroError("Width is zero");
	if (target.height == 0) throw ImageSizeIsZeroError("Height is zero");
	if (target.pixels == nullptr) throw ImageIsNullError("Target is null");

	for (uint i = 0; i < target.width * target.height; i++)
	{
		target.pixels[i] = color;
	}
}

Image horizontalMirror(const Image& source,uint* axis_ = nullptr)
{
	if (source.width == 0) throw ImageSizeIsZeroError("Width is zero");
	if (source.height == 0) throw ImageSizeIsZeroError("Height is zero");
	if (source.pixels == nullptr) throw ImageIsNullError("Source is null");

	Image result = createImage(source.width, source.height);
	
	uint axis;
	if(axis_ != nullptr) axis = *axis_;
	else axis = source.width / 2;
	
	for(uint i = 0;i < source.height;i++)
	{
		for(uint j = 0;j < source.width;j++)
		{
			result.pixels[i * source.width + (2 * axis - j)] = source.pixels[i * source.width + j];
		}
	}
	
	return result; 
}

Image verticalMirror(const Image& source,uint* axis_ = nullptr)
{
	if (source.width == 0) throw ImageSizeIsZeroError("Width is zero");
	if (source.height == 0) throw ImageSizeIsZeroError("Height is zero");
	if (source.pixels == nullptr) throw ImageIsNullError("Source is null");

	Image result = createImage(source.width, source.height);
	
	uint axis;
	if(axis_ != nullptr) axis = *axis_;
	else axis = source.height / 2;
	
	for(uint i = 0;i < source.height;i++)
	{
		for(uint j = 0;j < source.width;j++)
		{
			result.pixels[(2 * axis - i) * source.width + j] = source.pixels[i * source.width + j];
		}
	}
	
	return result; 
}

#endif

使用例

	Image img1;
	Image img2;
	Image img3;
	Image img4;
	Image img5;

	img1 = createImage(100, 100);
	img2 = createImage(100, 100);
	img5 = createImage(100,100);

	for (int i = 0; i < img2.height; i++)
	{
		Pixel red = {255, 0, 0};
		Pixel green = {0, 255, 0};
		Pixel blue = {0, 0, 255};
		img2.pixels[i * img2.width + 0] = red;
		img2.pixels[i * img2.width + 1] = green;
		img2.pixels[i * img2.width + 2] = blue;
	}

	try
	{
		Pixel bg = {0, 0, 0};
		Rect rect = {25,25,50,50};
		
		copyToAnother(img1, img2, 25, 25, &bg);
		copyToAnother(img1, img2, 50, 50, &bg);
		img3 = horizontalMirror(img1);
		img4 = verticalMirror(img1);
		copyToAnotherRect(img5,img1,0,0,rect,&bg);
	}
	catch (std::string e)
	{
		std::cout << e << std::endl;
	}

	releaseImage(img1);
	releaseImage(img2);
	releaseImage(img3);
	releaseImage(img4);
	releaseImage(img5);

你可能感兴趣的:(笔记,c++)