libjpeg (二)windows 使用,图片压缩

1.图片一般是质量压缩和缩放两种。我的需求是,我从摄像头拿到了rgb 数据流,知道分辨率,要先进行缩放,再进行质量压缩。

添加头文件:

extern "C" {
#include "jpeg/jpeglib.h"
#include "jpeg/cdjpeg.h"
}
#pragma comment (lib, "jpeg.lib")

一、输入的分辨率不定,需要先判断压缩比:bitWidth ,源数据,imageWidth 输出数据

  int getRatioSize(int bitWidth, int bitHeight,int imageWidth, int imageHeight) {
	
	// 缩放比
	int ratio = 1;
	// 缩放比,由于是固定比例缩放,只用高或者宽其中一个数据进行计算即可
	if (bitWidth > bitHeight && bitWidth > imageWidth) {
		// 如果图片宽度比高度大,以宽度为基准
		ratio = bitWidth / imageWidth;
	}
	else if (bitWidth < bitHeight && bitHeight > imageHeight) {
		// 如果图片高度比宽度大,以高度为基准
		ratio = bitHeight / imageHeight;
	}
	// 最小比率为1
	if (ratio <= 0)
		ratio = 1;
	return ratio;
}

二、根据缩放比进行缩放,我最后要保存成 640*480

unsigned char*  do_Stretch_Linear(int w_Dest, int h_Dest, int bit_depth, unsigned char *src, int w_Src, int h_Src)
{
	int sw = w_Src - 1, sh = h_Src - 1, dw = w_Dest - 1, dh = h_Dest - 1;
	int B, N, x, y;
	int nPixelSize = bit_depth / 8;
	unsigned char *pLinePrev, *pLineNext;
	unsigned char *pDest = new unsigned char[w_Dest*h_Dest*bit_depth / 8];
	unsigned char *tmp;
	unsigned char *pA, *pB, *pC, *pD;

	for (int i = 0; i <= dh; ++i)
	{
		tmp = pDest + i*w_Dest*nPixelSize;
		y = i*sh / dh;
		N = dh - i*sh%dh;
		pLinePrev = src + (y++)*w_Src*nPixelSize;
		//pLinePrev =(unsigned char *)aSrc->m_bitBuf+((y++)*aSrc->m_width*nPixelSize);
		pLineNext = (N == dh) ? pLinePrev : src + y*w_Src*nPixelSize;
		//pLineNext = ( N == dh ) ? pLinePrev : (unsigned char *)aSrc->m_bitBuf+(y*aSrc->m_width*nPixelSize);
		for (int j = 0; j <= dw; ++j)
		{
			x = j*sw / dw*nPixelSize;
			B = dw - j*sw%dw;
			pA = pLinePrev + x;
			pB = pA + nPixelSize;
			pC = pLineNext + x;
			pD = pC + nPixelSize;
			if (B == dw)
			{
				pB = pA;
				pD = pC;
			}

			for (int k = 0; k<nPixelSize; ++k)
			{
				*tmp++ = (unsigned char)(int)(
					(B * N * (*pA++ - *pB - *pC + *pD) + dw * N * *pB++
						+ dh * B * *pC++ + (dw * dh - dh * B - dw * N) * *pD++
						+ dw * dh / 2) / (dw * dh));
			}
		}
	}
	return pDest;
}

三、最后一步质量压缩:(注意这里是 RGB数据,三通道 24,如果是真彩色 32的四通道)

bool rgb2jpgCompress(const char * filename, unsigned char* image_buffer, 
	 int quality, int image_height, int image_width, unsigned long* bufferSize)
  {

	  if (filename == NULL || image_buffer == NULL) return false;

	  struct jpeg_compress_struct cinfo;
	  struct jpeg_error_mgr jerr;
	  FILE * outfile;        /* target file */
	  JSAMPROW row_pointer[1];    /* pointer to JSAMPLE row[s] */
	  int row_stride;        /* physical row width in image buffer */
	  cinfo.err = jpeg_std_error(&jerr);
	  /* Now we can initialize the JPEG compression object. */
	  jpeg_create_compress(&cinfo);
	   
	 //  if ((outfile = fopen(filename, "wb")) == NULL) {
	//	  fprintf(stderr, "can't open %s\n", filename);
	//	  return false;
	//  } 
	//  jpeg_stdio_dest(&cinfo, outfile);

	// 输出图像数据缓冲区
	 // unsigned char* outBuffer = nullptr;
	  // 输出图像数据缓冲区长度(压缩后的图像大小)
	  //unsigned long bufferSize = 1024*1024*5;
	  jpeg_mem_dest(&cinfo, &jpgMemery, bufferSize); // 设置内存输出缓冲区
	  cinfo.image_width = image_width;     /* image width and height, in pixels */
	  cinfo.image_height = image_height;
	  cinfo.input_components = 3;        /* # of color components per pixel */
	  cinfo.in_color_space = JCS_RGB;     /* colorspace of input image */

	  jpeg_set_defaults(&cinfo);
	  jpeg_set_quality(&cinfo, quality, TRUE /* limit to baseline-JPEG values */);
	  
	  jpeg_start_compress(&cinfo, TRUE);
	
	 // compress_instance.start_output(cinfo);
	  row_stride = image_width * 3;    /* JSAMPLEs per row in image_buffer */

	  while (cinfo.next_scanline < cinfo.image_height) {
		  row_pointer[0] = &image_buffer[cinfo.next_scanline * row_stride];
		//  printf("cinfo.next_scanline * row_stride:%d,row:%u\n", cinfo.next_scanline  , row_pointer[0]);
		  (void)jpeg_write_scanlines(&cinfo, row_pointer, 1);
	  }

	  jpeg_finish_compress(&cinfo);
	//  fwrite(jpgMemery,1, bufferSize, outfile);
	//  fclose(outfile);
	  jpeg_destroy_compress(&cinfo);
	  return true;
  }

如果想保存成图片打开 这里就可以;

//  fwrite(jpgMemery,1, bufferSize, outfile);
    //  fclose(outfile);

API上体使用有一个写的比较好:

https://blog.csdn.net/xipiaoyouzi/article/details/53257720

https://cloud.tencent.com/developer/article/1188654

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
可以使用libjpeg对8bit图像进行压缩,具体步骤如下: 1. 引入libjpeg的头文件: ```c #include <jpeglib.h> ``` 2. 定义需要压缩的图像数据和相关参数: ```c JSAMPLE *image_buffer; // 图像数据 int image_width; // 图像宽度 int image_height; // 图像高度 int image_channels; // 图像通道数 ``` 3. 创建jpeg压缩对象: ```c struct jpeg_compress_struct cinfo; // 压缩对象 struct jpeg_error_mgr jerr; // 错误处理对象 cinfo.err = jpeg_std_error(&jerr); jpeg_create_compress(&cinfo); ``` 4. 设置压缩参数: ```c cinfo.image_width = image_width; cinfo.image_height = image_height; cinfo.input_components = image_channels; cinfo.in_color_space = JCS_RGB; jpeg_set_defaults(&cinfo); jpeg_set_quality(&cinfo, 80, TRUE); ``` 5. 指定压缩输出目标: ```c FILE *outfile; outfile = fopen("output.jpg", "wb"); jpeg_stdio_dest(&cinfo, outfile); ``` 6. 开始压缩: ```c int row_stride = image_width * image_channels; JSAMPROW row_pointer[1]; jpeg_start_compress(&cinfo, TRUE); while (cinfo.next_scanline < cinfo.image_height) { row_pointer[0] = &image_buffer[cinfo.next_scanline * row_stride]; jpeg_write_scanlines(&cinfo, row_pointer, 1); } jpeg_finish_compress(&cinfo); fclose(outfile); ``` 7. 释放压缩对象: ```c jpeg_destroy_compress(&cinfo); ``` 以上是使用libjpeg对8bit图像进行压缩的基本步骤。需要注意的是,压缩后的图像数据将保存在指定的输出文件中,可以在需要时读取并解压缩。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

恋恋西风

up up up

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值