求BMP转PNG压缩和PNG解压缩源代码

huanglin03 2015-07-01 10:15:35
100大粉献上,要的拿走
...全文
198 3 打赏 收藏 转发到动态 举报
写回复
用AI写文章
3 条回复
切换为时间正序
请发表友善的回复…
发表回复
huanglin03 2015-07-02
  • 打赏
  • 举报
回复
多谢2楼提供的链接,粉给你,要是能再知道BMP压缩为PNG的原理就好了
mxway 2015-07-02
  • 打赏
  • 举报
回复
http://libmng.com/pub/png/libpng.html开源c++ png库。完整源码楼主到www.ipmsg.org下载完整代码(楼主下载飞鸽传书后就不再需要再下载libpng库了,因为飞鸽传书bmp转png就是libpng)。bmp转png完整代码在飞鸽传书的image.cpp文件中。 下面是飞鸽伟书将HBITMAP转为png图片的部分源码
VBuf *BmpHandleToPngByte(HBITMAP hBmp)
{
	BITMAP		bmp;
	BITMAPINFO	*bmi = NULL;
	int			palette, total_size, header_size, data_size, line_size;
	HWND		hWnd = ::GetDesktopWindow();
	HDC			hDc = NULL;
	VBuf		bmpVbuf;
	png_struct	*png  = NULL;
	png_info	*info = NULL;
	png_color_8	sbit;
	png_byte	**lines = NULL;
	VBuf		*vbuf = NULL, *ret = NULL;

	if (!::GetObject(hBmp, sizeof(bmp), &bmp)) return NULL;

	//if (bmp.bmBitsPixel < 24)
	bmp.bmBitsPixel = 24;

	line_size   = bmp.bmWidth * ALIGN_SIZE(bmp.bmBitsPixel, 8) / 8;
	line_size   = ALIGN_SIZE(line_size, 4);
	data_size   = line_size * bmp.bmHeight;
	palette     = bmp.bmBitsPixel <= 8 ? 1 << bmp.bmBitsPixel : 0;
	header_size = sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * palette;
	total_size	= header_size + data_size;

	if (!bmpVbuf.AllocBuf(total_size)) return	NULL;
	bmi = (BITMAPINFO *)bmpVbuf.Buf();

	bmi->bmiHeader.biSize         = sizeof(BITMAPINFOHEADER);
	bmi->bmiHeader.biWidth        = bmp.bmWidth;
	bmi->bmiHeader.biHeight       = bmp.bmHeight;
	bmi->bmiHeader.biPlanes       = 1;
	bmi->bmiHeader.biBitCount     = bmp.bmBitsPixel;
	bmi->bmiHeader.biCompression  = BI_RGB;
	bmi->bmiHeader.biClrUsed      = palette;
	bmi->bmiHeader.biClrImportant = palette;

	if (!(hDc = ::GetDC(hWnd)) ||
		!::GetDIBits(hDc, hBmp, 0, bmp.bmHeight, (char *)bmi + header_size, bmi, DIB_RGB_COLORS)) {
		goto END;
	}

	if (!(png = png_create_write_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0))) return NULL;
	if (!(info = png_create_info_struct(png))) goto END;
	if (!(vbuf = new VBuf(0, total_size))) goto END;

	png_set_write_fn(png, (void *)vbuf, (png_rw_ptr)png_vbuf_wfunc,
					(png_flush_ptr)png_vbuf_wflush);

	if (palette) {
		png_color	png_palette[256];
		for (int i=0; i < palette; i++) {
			png_palette[i].red		= bmi->bmiColors[i].rgbRed;
			png_palette[i].green	= bmi->bmiColors[i].rgbGreen;
			png_palette[i].blue		= bmi->bmiColors[i].rgbBlue;
		}
		png_set_IHDR(png, info, bmp.bmWidth, bmp.bmHeight, bmp.bmBitsPixel,
					PNG_COLOR_TYPE_PALETTE,
					PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
		png_set_PLTE(png, info, png_palette, palette);
	}
	else {
		png_set_IHDR(png, info, bmp.bmWidth, bmp.bmHeight, 8,
					bmp.bmBitsPixel > 24 ? PNG_COLOR_TYPE_RGB_ALPHA  : PNG_COLOR_TYPE_RGB,
					PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
	}
	sbit.red = sbit.green = sbit.blue = 8;
	sbit.alpha = bmp.bmBitsPixel > 24 ? 8 : 0;
	png_set_sBIT(png, info, &sbit);

	if (setjmp(png_jmpbuf(png))) {
		goto END;
	}
	else {
		png_write_info(png, info);
		png_set_bgr(png);

		lines = (png_byte **)malloc(sizeof(png_bytep *) * bmp.bmHeight);

		for (int i = 0; i < bmp.bmHeight; i++) {
			lines[i] = bmpVbuf.Buf() + header_size + line_size * (bmp.bmHeight - i - 1);
		}
		png_write_image(png, lines);
		png_write_end(png, info);
		ret = vbuf;
	}

END:
	if (png) png_destroy_write_struct(&png, &info);
	if (hDc) ::ReleaseDC(hWnd, hDc);
	if (lines) free(lines);
	if (!ret && vbuf) delete vbuf;
	return	ret;
}
ForestDB 2015-07-01
  • 打赏
  • 举报
回复
分不要了,自己搜去吧。

15,440

社区成员

发帖
与我相关
我的任务
社区描述
C/C++ 非技术区
社区管理员
  • 非技术区社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧