请问大虾们,如何用C++得到缩略图啊,高压缩比的

Rossoneri 2011-04-19 06:41:35
我用imagemagick里面的zoom()函数转换一个60多兆的相机图片(4288*2848),得到200*133的147K,1024*680的3.61M,虽然很小了,可是跟预期还是有很大差距啊,像windows上显示的缩略图肯定很小的,用C++有没有更好的方法,多谢。
...全文
641 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
Rossoneri 2011-04-20
  • 打赏
  • 举报
回复
LS的需要自己写算法啊,有没有现成的函数啊
我又试了下,发现是图片里面包含了很多exif信息,什么模式了,曝光了之类的无用信息,要是能把这些信息去掉就好了,有没有知道的兄弟姐妹们啊,拜托啊
方紫涵 2011-04-20
  • 打赏
  • 举报
回复
up 玄机
pathuang68 2011-04-20
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 rocco22 的回复:]

LS的需要自己写算法啊,有没有现成的函数啊
我又试了下,发现是图片里面包含了很多exif信息,什么模式了,曝光了之类的无用信息,要是能把这些信息去掉就好了,有没有知道的兄弟姐妹们啊,拜托啊
[/Quote]

4L给的不就是函数么,还给出了main函数告诉你怎么用...当然图像像素的像素,你需要自己改动一下(用参数传入)这个不难吧?

bmp<->jpeg转换,可以用jpeglib。
Meteor_Code 2011-04-20
  • 打赏
  • 举报
回复
xinmage,帮你解决你的图片问题
请关注我的下载

http://download.csdn.net/source/1439447
xmu_才盛 2011-04-20
  • 打赏
  • 举报
回复
up 玄机,,, 原来是搞图像的啊,,,

楼主既然用c++,就别想让别人给你做事。。。。

就跟开跑车开车一样, 还想让别人给你挂挡。。

那就应该用自动挡的大众去。。。
pathuang68 2011-04-19
  • 打赏
  • 举报
回复
这是3楼说的原理的VC优化实现:

// imagetest.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <windows.h>
#include <stdio.h>
#include <assert.h>


//------------------------------------------------
class Rothstein
{
public:
Rothstein(int p, int q);
int operator[] (int i) { return myData[i]; }
void Permute();
void PrintData();

~Rothstein();


private:
char *myData;
int myP, myQ;
};

class RowRothstein280
{
public:
RowRothstein280(int largerSize, int bpp); //increment according to byte per pixel
int operator[] (int i) { return myData[i]; }
void PrintData();

private:
int myData[280];
};

class ColRothstein210
{
public:
ColRothstein210(int largerSize, int bpl); //increment according to byte perl line
int operator[] (int i) { return myData[i]; }
void PrintData();

private:
int myData[210];
};

Rothstein::Rothstein(int p, int q)
{
myP = p;
myQ = q;
myData = new char[p];

if (p <= q) {
memset(myData, 1, p);
return;
}

char *ptr = myData;
int diff = p - q;
int curr = q;
for (int i=0; i< p; i++) //if we want to permute the code, we need <<1
{
if(curr < p)
{
*ptr = 0;
curr += q;
}
else
{
*ptr = 1;
curr -= diff;
}
ptr++;
}
}

void Rothstein::Permute()
{
int temp = myData[0];

for (int i=0; i<myP-1; i++)
myData[i] = myData[i+1];

myData[myP-1] = temp;
}

void Rothstein::PrintData()
{

for (int i=0; i<myP; i++)
{
printf("%d\t", myData[i]);
}
printf("\n");
}

Rothstein::~Rothstein()
{
delete myData;
}

//Rothstein of size 280, for Row
// bpp = byte per pixel
RowRothstein280::RowRothstein280(int largerSize, int bpp)
{
// assert(largerSize > 280);

Rothstein rot(largerSize, 280);
int j = 0;
int oldData = 0;
for(int i = 0; i< largerSize; i++)
{
if (rot[i])
{
myData[j++]= (i - oldData)*bpp; //increment in bytes per pixel * number of pixels
oldData = i;
}
}
//printf("j is %d \n", j);

}

void RowRothstein280::PrintData()
{

for (int i=0; i<280; i++)
{
printf("%d\t", myData[i]);
}
// printf("\n");
}

ColRothstein210::ColRothstein210(int largerSize, int bpl)
{
// assert(largerSize > 210);

Rothstein rot(largerSize, 210);
int j = 0;
int oldData =0;
for(int i = 0; i< largerSize; i++)
{
if (rot[i])
{
myData[j++]= (i - oldData) * bpl; //increment by number of lines * bytes per line
oldData = i;
}
}
// printf("j is %d \n", j);

}

void ColRothstein210::PrintData()
{

for (int i=0; i<210; i++)
{
printf("%d\t", myData[i]);
}
printf("\n");
}

/*

HeavyRothstein

If we are shrinking an image from a columns to b columns, we are interested
in the Rothstein code for p = a, q = b.

If we are expanding an image from a columns to b columns, we are interested
in the Rothstein code for p = b, q = a.

HeavyRothstein takes two dimensions and automatically constructs a Rothstein
code with p set to the larger dimension and q set to the smaller dimension.

*/

//int minval(int a, int b) { return a < b ? a : b; }
//int maxval(int a, int b) { return a > b ? a : b; }

class HeavyRothstein : public Rothstein
{
public:
HeavyRothstein(int a, int b) : Rothstein(max(a, b), min(a, b)) {}
};


BYTE* bits = NULL;
BYTE* newbits = NULL;
FILE* file = NULL;
BITMAPFILEHEADER bf;
unsigned newwidth, newheight, newimagesize, newbfsize;
unsigned bmiSize;
unsigned imageSize;
int bpp, bpl;
RowRothstein280 *rot280;
ColRothstein210 *rot210;

void InitDevice()
{
//-------800x600 to 280x210
newwidth = 280;
newheight = 210;

//-------byte per pixel 3 original image byte per line 800 x 3 = 2400
bpp = 3;
bpl = 800*bpp; //2400

rot280 = new RowRothstein280(800, bpp);
rot210 = new ColRothstein210(600, bpl);

}



//from 800x600 to 280x210
void ResizeImage800to280(unsigned char* src, unsigned char* dst)
{
unsigned char* oldp; //pointer to the pix in the old image
int oldcol = 0;

for(int row = 0; row < 210; row++)
{
src += (*rot210)[row];
oldp = src;
for (int col = 0; col < 280; )
{ //unroll 10 times;
oldp += (*rot280)[col++];
memcpy(dst, oldp, bpp);
dst+=bpp;
oldp += (*rot280)[col++];
memcpy(dst, oldp, bpp);
dst+=bpp;
oldp += (*rot280)[col++];
memcpy(dst, oldp, bpp);
dst+=bpp;
oldp += (*rot280)[col++];
memcpy(dst, oldp, bpp);
dst+=bpp;
oldp += (*rot280)[col++];
memcpy(dst, oldp, bpp);
dst+=bpp;
oldp += (*rot280)[col++];
memcpy(dst, oldp, bpp);
dst+=bpp;
oldp += (*rot280)[col++];
memcpy(dst, oldp, bpp);
dst+=bpp;
oldp += (*rot280)[col++];
memcpy(dst, oldp, bpp);
dst+=bpp;
oldp += (*rot280)[col++];
memcpy(dst, oldp, bpp);
dst+=bpp;
oldp += (*rot280)[col++];
memcpy(dst, oldp, bpp);
dst+=bpp;
}
}
}

//-----------------------end 800x600 to 280x210 bpp=3--------------------------------------------------------



struct {
BITMAPINFOHEADER bmiHeader;
RGBQUAD bmiColors[256];
} bmi;

void LoadBMP(char* filename)
{

if (!(file = fopen(filename, "rb"))) {
goto done;
}

if (fread(&bf, 1, sizeof(bf), file) != sizeof(bf)) {
goto done;
}

if (bf.bfType != *(WORD*) "BM") {
goto done;
}

bmiSize = bf.bfOffBits - sizeof(bf);
if (bmiSize > sizeof(bmi)) {
goto done;
}
if (fread(&bmi, 1, bmiSize, file) != bmiSize) {
goto done;
}
imageSize = (bmi.bmiHeader.biWidth * bmi.bmiHeader.biBitCount / 8 + 3 & ~3) * bmi.bmiHeader.biHeight;
bits = new BYTE[imageSize];


if (fread(bits, 1, imageSize, file) != imageSize) {
goto done;
}

printf("image size is %d\n", imageSize);
printf("color is %d\n", bmi.bmiHeader.biBitCount);
printf("width is %d height is %d\n", bmi.bmiHeader.biWidth, bmi.bmiHeader.biHeight);

//image = LoadBMP((BITMAPINFO*) &bmi, bits);

done:
if (file) {
fclose(file);
}

}

// CopyPixel will copy a pixel

inline void CopyPixel(unsigned char *dst, unsigned char *src, int byteperpix)
{
for (int i=0; i<byteperpix; i++)
*dst++ = *src++;
}


//regular Rothstein algorithm
void ResizeImage(unsigned char* src, int sw, int sh, int sp, unsigned char* dst, int dw, int dh, int bpp)
{
unsigned char* oldp; //pointer to the pix in the old image
HeavyRothstein rothrow(dw, sw);
HeavyRothstein rothcol(dh, sh);
int oldcol = 0;

for (int col = 0; col < dh; col++)
{
// If shrinking in height, find a 1 in the Rothstein code
if (dh < sh) {
while (rothcol[oldcol] == 0) {
oldcol++;
src += sp;
}
}

// Resize a single row of the image.
oldp = src;

int oldrow = 0;

for(int row = 0; row < dw; row++)
{
// If shrinking in width, find a 1 in the Rothstein code
if (dw < sw) {
while (rothrow[oldrow] == 0) {
oldrow++;
oldp += bpp;
}
}

CopyPixel(dst, oldp, bpp);
dst += bpp;

// Advance the "old" pointer
// the # of cols specified in the Rothstein code
if (dw < sw) {
oldrow++;
oldp += bpp;
} else {
oldrow += rothrow[row];
oldp += rothrow[row] * bpp;
}
}

// Advance the "old" pointer the # of rows specified in the Rothstein code
if (dh < sh) {
oldcol++;
src += sp;
} else {
oldcol += rothcol[col];
src += sp * rothcol[col];
}
}
}

void ProcessBMP(char* filename)
{

// HeavyRothstein rotrow(bmi.bmiHeader.biWidth, newwidth);
// HeavyRothstein rotcol(bmi.bmiHeader.biHeight, newheight);

newimagesize = (newwidth* bmi.bmiHeader.biBitCount / 8 + 3 & ~3)* newheight;

newbits = new BYTE[newimagesize];

int bytes_per_line = bmi.bmiHeader.biBitCount / 8 * bmi.bmiHeader.biWidth + 3 & ~3;

// ResizeImage((unsigned char*) bits, bmi.bmiHeader.biWidth, bmi.bmiHeader.biHeight, bytes_per_line, (unsigned char*) newbits, newwidth, newheight, bmi.bmiHeader.biBitCount / 8);


ResizeImage800to280((unsigned char*) bits, (unsigned char*) newbits);

int filesize = sizeof(bf)+ bmiSize +newimagesize;
bf.bfSize = filesize;
bmi.bmiHeader.biWidth = newwidth;
bmi.bmiHeader.biHeight = newheight;
bmi.bmiHeader.biSizeImage = newimagesize;


if (!(file = fopen(filename, "wb"))) {
goto done;
}
if (fwrite(&bf, 1, sizeof(bf), file) != sizeof(bf)) {
goto done;
}

if (fwrite(&bmi, 1, bmiSize, file) != bmiSize) {
goto done;
}

if (fwrite(newbits, 1, newimagesize, file) != newimagesize) {
goto done;
}


done:
if (file) {
fclose(file);
}
if (bits) {
delete [] bits;
}
if (newbits) {
delete [] newbits;
}

if( rot280) {
delete rot280;
}
if( rot210) {
delete rot210;
}

}

int main(int argc, char* argv[])
{
char* infile;
char* outfile;

//if(argc > 2)
{
/*
infile = "test.bmp";
newwidth = 800;
newheight = 600;
outfile = "test1.bmp"; //argv[2];
*/
/*
infile = "wallpaper1.bmp"; //argv[1];
newwidth = 640;
newheight = 480;
outfile = "test.bmp"; //argv[2];
*/
infile = "test.bmp"; //argv[1];
outfile = "test2.bmp"; //argv[2];

InitDevice();

printf("in is %s\n", infile);
printf("out is %s\n", outfile);
LoadBMP(infile);
ProcessBMP(outfile);
}

// HeavyRothstein rot(800, 280);
// rot.PrintData();
// rot280.PrintData();
printf("Hello World!\n");
// rot210.PrintData();

// HeavyRothstein rot1(600, 210);
// rot1.PrintData();


return 0;
}
pathuang68 2011-04-19
  • 打赏
  • 举报
回复
俺在Berkley的网站,看到他们缩小图片的一种做法是这样的:

先把那个60M+的图片,转换成BMP(假定是12 x 12),没点24bits(RGB各一个byte):
。 。 。 。 。 。 。 。 。 。 。 。
。 。 。 。 。 。 。 。 。 。 。 。
。 。 。 。 。 。 。 。 。 。 。 。
。 。 。 。 。 。 。 。 。 。 。 。
。 。 。 。 。 。 。 。 。 。 。 。
。 。 。 。 。 。 。 。 。 。 。 。
。 。 。 。 。 。 。 。 。 。 。 。
。 。 。 。 。 。 。 。 。 。 。 。
。 。 。 。 。 。 。 。 。 。 。 。
。 。 。 。 。 。 。 。 。 。 。 。
。 。 。 。 。 。 。 。 。 。 。 。
。 。 。 。 。 。 。 。 。 。 。 。

假定你要让它变成2 x 2的图像,你可以将上面的点阵分成2 x 2个 6 x 6的点阵。
针对每个6 x 6的点阵,把所有点的R、G、B的值加起来,分别得到sum_R、sum_G和sum_B,那么得到
点的颜色值就是(sum_R/36, sum_G/36, sum_B/36)

这样以来,36个点就缩小为一个点了。

完成后,再把这个缩小了的bmp转换为jpg就可以了。
Rossoneri 2011-04-19
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 wocaoqwer 的回复:]
再调用一次 不就更小了
[/Quote]
早试过了,不论用多少次,跟用一次一模一样,大小不会变
fight_flight 2011-04-19
  • 打赏
  • 举报
回复
再调用一次 不就更小了
内容概要:本文系统研究了Picard迭代法在非线性常微分方程参数估计中的应用,深入阐述了该方法的数学原理及其在参数辨识中的收敛性与稳定性优势。通过构建最小化误差的目标函数,并结合数值积分技术,采用迭代方式逐步逼近系统的真实参数值,有效解决了非线性动态系统中因缺乏解析解而难以进行精确建模的问题。文中提供了完整的Matlab代码实现,涵盖模型定义、迭代求解、参数更新与结果可视化等关键环节,增强了方法的可操作性与工程实用性。研究通过典型非线性系统案例验证了算法的有效性,展示了其在科学计算与工程建模中的良好适应性与推广潜力。; 适合人群:具备常微分方程理论、数值分析基础及Matlab编程能力,从事系统建模、参数辨识、动力学仿真等相关方向的研究生、科研人员和工程技术开发者。; 使用场景及目标:①解决实际工程中非线性微分方程模型的未知参数估计问题;②深入理解Picard迭代法在科学计算中的实现机制与数值特性;③为学术论文复现、科研项目开发或课程设计提供可运行、易调试的技术方案与代码参考。; 阅读建议:建议读者结合文中的数学推导与Matlab代码逐行分析,重点关注迭代流程、目标函数构造与数值积分的耦合实现,通过修改模型结构或噪声条件进行扩展实验,以深化对算法鲁棒性与适用边界的理解。配套资源可通过指定公众号和网盘链接获取,推荐同步学习以加速科研进程。
内容概要:本文详细介绍了一种基于多尺度集成极限学习机(Extreme Learning Machine, ELM)的回归方法,并提供了完整的Matlab代码实现。该方法通过构建多尺度特征表示与集成学习机制,有效提升了ELM在处理非线性、维复杂数据时的预测精度与模型鲁棒性,特别适用于时间序列回归任务。文档不仅阐述了算法的核心原理与技术流程,还系统展示了其在风电功率预测等工程场景中的应用潜力。同时,文中附带了丰富的科研仿真案例集合,涵盖智能优化算法、深度学习、信号处理、电力系统调度等多个前沿方向,体现了多学科交叉融合的技术优势与实践价值。; 适合人群:具备一定Matlab编程能力,从事科学研究或工程应用的研究生、科研人员及工程技术开发者,尤其适合专注于机器学习、智能算法优化、新能源预测与电力系统建模等相关领域的专业人员。; 使用场景及目标:①用于风电、光伏、负荷等时间序列数据的精度回归预测任务;②为科研工作者提供可复现的多尺度集成ELM模型代码框架,支持快速算法验证与二次开发;③满足实际工程项目中对效建模、实时预测与智能决策的技术需求。; 阅读建议:建议读者结合所提供的Matlab代码进行动手实践,深入理解多尺度特征构造与集成策略的设计思想,同时可参考文档中其他相关算法案例进行横向比较与综合应用,以提升整体科研创新能力。

65,213

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

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