《VB.NET》如何pakv3可以删除吗MP3的 ID3v1 ID3v2 。求代码。

QQ音乐下载设置里的Mp3标签写入类型 ID3v1 ID3v2 ID3v1& ID3v2 什么意思_百度知道
色情、暴力
我们会通过消息、邮箱等方式尽快将举报结果通知您。
QQ音乐下载设置里的Mp3标签写入类型 ID3v1 ID3v2 ID3v1& ID3v2 什么意思
mp3标签是位于一个 MP3 文件的开头或末尾的若干字节内的数据格式,附加了关于该 MP3 的歌曲名、演唱者、专辑名、标题、年代、歌曲风格、类型、备注等信息.(相当于注释)
id3v2是保存在mp3文件开头;id3v1是保存在mp3文件结尾;id3v2&id3v1是同时保存,优先id3v2。要是下载到手机后显示未知艺术家、未知专辑或者乱码,就换一种写入类型尝试。
采纳率:64%
为您推荐:
其他类似问题
id3v2的相关知识
等待您来回答1831人阅读
数据处理训练(1)
最近在研究MP3中图片提取,发现这篇文章,转到自己博客,留用。原文出处
看到标题估计有人懵了,不过对于用到的人可以说是眼前一亮啊。做了点这个小东西,断断续续的花了我好长时间。本来不想写,但是网上的资料都是坑爹呢。
中国的抄袭果然是根深蒂固啊。上到机构、砖家、公司,下到各种各种技术博客的copy paste.有好多弄出来的东西都是错误的。自己都没实践,哪来的优越感放网上。
&废话少说,开正题。
1.mp3标签简介
我们得到一个mp3文件后,通过播放器,或是右击看其属性,我们会发现除了文件大小和名字,还会有一些其他信息。比如作者,类型,年月日,有的还有一个小图片。
这些信息都是在mp3的源文件内。源文件内除了音乐的数据,还会有一些标识性信息。在计算机的世界,几乎所有的文件都是这样,不然系统怎么直到你这一堆二进制代码是什么东西,我要对它做什么。
在mp3的数据内,有多种标签标识它的信息,最常见的就是ID3。一开始是ID3V1,这个标签在mp3的最后128个字节。前3个字节是TAG,用来标识标签的开始。在linux下,你可以用vim直接打开一个mp3文件,移到最后看一下。在windows下可以用UItraEdit。后面不同的标签会有不同的标识符,每个标识符后面就是相应的数据。ID3V1的各标识符的大小都是固定的,很好读取。不过有些限制,就是不能存中文,没有图片,表示的内容也有限。
&&& 图:ID3V1标签结构
后来ID3升级到ID3V2。ID3V2有4个版本,现在常见的应该是ID3V2.4,也就是第4个版本。ID3V2的标签在mp3的开头。前10个字节是整个标签的标签头,记录了这个标签的标识,版本,整个标签的大小。前3个是标识位,其值为ID3,表示标签存在,如果前三个字节不是ID3,那就表示没有ID3V2的标签。然后一个字节是版本号,下一个字节为副版本号,再下一个是标志位。这三个字节都没太大用。最后4个字节是标签的大小,这个挺重要。
&图:ID3V2标签结构
图:ID3V2头结构
说一下这四个字节是如何计算标签大小的。你最好用BYTE类型或是unsigned char类型类保存这四个字节,如果高位为1,会被认为负数。不过这里不用怕这个,因为这四个字节的每一个字节的最高位都是0,况且计算时去掉这四位。什么意思呢?就是本来是用4个字节,也就是32位的二进制数来表示标签大小,在这里把最高位都制为0,并且去掉,不加入计算。也就相当于是28位2进制数来表示标签大小。具体原因不明,反正成为了规定,就遵循吧。计算公式:
int&Len = (size[0]&0x7f)*0x200000
&&+(size[1]&0x7f)*0x4000
&&+(size[2]&0x7f)*0x80
&&+(size[3]&0x7f);
得到的数就是标签的大小,也就是多少个字节。但是这个大小是不包括标签头的10个字节的。
读完这10个标签头的字节,再往下读10个字节就是标签帧的帧头了,和标签头的10个字节一样,它也记录了标签帧的大小,标签的内容和标志。
char FrameID[4]; /*用四个字符标识一个帧,说明其内容*/
BYTE&Size[4]; /*帧内容的大小,不包括帧头,不得小于1*/
char Flags[2]; /*存放标志,只定义了6位*/
&图:ID3V2帧头结构
这就是帧头的格式,比如你如果读的FrameID是TIT2的话,那就表示这个帧的数据部分保存的是歌曲名,这都是有一一对应的表的。
帧的大小的计算和标签头不一样,没有要去掉的位,32个2进制全用来表示这个帧除了帧头10个字节外的剩下的数据部分的大小。计算公式:
int Len= size[0]*0x1000000
&&&+size[1]*0x10000
&&&+size[2]*0x100
&&&+size[3];
在这里size的类型必须是无符号的单字节类型。就是上面我说的BYTE或是unsigned char。不然你可能计算的值很大或是负数。
标识位可以不用考虑,FrameID对应表,可以查一下,这里只说两个,TIT2表示是歌的名字,APIC表示是图片。
2.读取mp3内部中文信息
比如上面如果帧的ID是TIT2,那就表示这个帧里面保存的是歌曲的名字。我们通过size来计算出帧的大小(当然是不包括帧头的10个字节),那么我们就从帧头的下一个字节往后读Len个字节,那么这里面的数据就是歌曲名字。帧与帧之间是紧密挨着的,Len+1个字节开始就是下一个帧的帧头了。
其实我们读取的Len个字节并不全是歌曲名字,因为如果是字符串的内容的话,帧头下面的第一个字节,也就是Len个字节的第一个字节是用来表示这个字符串使用什么编码方式编码的。不同的编码方式,读取的方式不一样,必须要标明,不然你输出的内容就是一堆乱码。这里有一个对应表:
0代表字符使用ISO-8859-1编码方式;
1代表字符使用UTF-16编码方式;
2代表字符使用 UTF-16BE编码方式;
3代表字符使用UTF-8编码方式。
目前只有4中编码方式,你可以计算第一个字节的大小,然后和这个表对应,就能直到使用什么编码方式保存的数据了。
如果是0或是3这两种编码方式的话,你就用一个char的数组去读这个数据,然后输出,就是你想要的内容。
如果是1或2这两种编码的话,那就要用宽字节数组去读,就是wchar_t声明的数组读取。
记住要跳过第一个字节。
3.读取图片
如果你想读取mp3里面的专辑图片的话,就要找到APIC标签,然后计算出标签大小。APIC标签的数据部分也比较特殊,首先在数据的前几个字节里面,并没有图片的数据,而是告诉你这里保存的图片数据是什么格式的,大部分都是jpeg的,因为占地小。
在数据部分前几个字节会出现一个特殊标志 image/jpeg 来标明下面的数据是jpeg格式的,如果是其他格式则为image/png image/bmp,jpeg的格式可能会有jpg peg等格式来表示。也就是image/jpg 也表示是jpeg的。
然后开始读取图片数据,在image/jpeg这个标志后面就保存了图片的数据,不过并不是image/jpeg结束后第一个字节就是图片数据,在这里image/jpeg出现的位置和图片的数据开始的位置都是不固定的,就是在它们前后可能都有一些空字节,所以要判断一下。
我们查询jpeg的图片格式可以知道当连着的两个字节是16进制0xFFD8时,就表示图片的数据开始的位置,所以你要从这里开始读,包括0xFFd8也要读进去,也就是FF是第一个字节,D8是第二个字节,然后往下读,直到读到连续两个字节是0xFFD9,这就表示图片数据读完了,记住也要把这两个结束字符读进去。
前面我们已经计算出这个APIC的大小,你可以用这个大小减去不是图片数据的字节数,从0xFFD8开始读剩下的字节数就可以了。
我们把读到的数据放到数组里,然后写到一个空文件里,就是一幅jpeg的图片了
4.图片转换
得到jpeg图片后,如果我们想转换成其它图片,那么就需要进行图片转码了。jpeg图像之所以很小,是因为里面进行了多次压缩。先要把计算机上常用的RGB图像源数据转换成YCrCb,然后进行DCT变换,重排DCT结果,量化,这样就会是图像数组的左上角是相似的数字,剩下的大部分是0。然后是RLE编码,huffman编码。最后编出来一堆你不认识的值,加上各种段,标志,保存成jpeg。所以如果我们想转换成其它图片的话,就要反着来一边。这个工作比较麻烦,也比较复杂。所以我们可以用第三方的库来实现。我这里用的是jpeglib。
然后下载包。虽然它写着是for windows的,其实里面是一个linux下的工程,你需要的东西必须编译一下,才能生成。
在包的里面有一个install.txt的文档,里面告诉你在不同的环境下如何编译,我截取一段在windows下用vs2010编译的部分:
Microsoft Windows, Microsoft Visual C++ 2010 Developer Studio (v10):
We include makefiles that should work as project files in Visual Studio
2010 or later.& There is a library makefile that builds the IJG library
as a static Win32 library, and application makefiles that build the sample
applications as Win32 console applications.& (Even if you only want the
library, we recommend building the applications so that you can run the
self-test.)
1. Open the command prompt, change to the main directory and execute the
&& command line
&NMAKE /f makefile.vc& setup-v10
&& This will move jconfig.vc to jconfig.h and makefiles to project files.
&& (Note that the renaming is critical!)
2. Open the solution file jpeg.sln, build the library project.
&& (If you are using Visual Studio more recent than 2010 (v10), you'll
&& probably get a message saying that the project files are being updated.)
3. Open the solution file apps.sln, build the application projects.
4. To perform the self-test, execute the command line
&NMAKE /f makefile.vc& test-build
5. Move the application .exe files from `app`\Release to an
&& appropriate location on your path.
There seems to be an optimization bug in the compiler which causes the
self-test to fail with the color quantization option.
We have disabled optimization for the file jquant2.c in the library
project file which causes the self-test to pass properly.
也就是先执行NMAKE /f makefile.vc& setup-v10,然后用vs打开jpeg.sln工程,编译一下,然后打开apps.sln工程,里面有好几个工程,每一个都编译一遍,这时候你得到这四个文件:jconfig.h jmorecfg.h jpeg.lib jpeglib.h,把它们放到你的工程目录下,然后在程序开始包含头文件的时候包含进去就可以了。然后上网搜一下copy 粘贴最多的那片文章,把里面代码稍微改一下就可以用了。后面的命令是测试用的,不用管。
如何执行NMAKE /f makefile.vc& setup-v10?先打开开始菜单,找到visual studio2010的文件夹,找到visual studio tools,然后在里面打开x64 cross tools command,进入到makefile.vc目录下,也就是你解压的目录下,执行就可以了。在这个command下切换目录是,先输入文件所在盘符名,比如C:,回车,然后cd 加文件名进入即可。
这个第三方库帮我们把jpeg的解码都做了,我们获得其中的图像数据RGB,然后上网查一下bmp的格式,然后把那篇拷贝粘贴最多的程序,改一下把数据写进去就可以了。
bmp格式很简单,只有两个头标签,然后是把RGB数据写到标签后面就行了,没有压缩,所以比jpeg大十几倍或几十倍。
在这里我是用的c c++来实现的,在windows下。
这里必须先读取mp3源文件,然后对每段数据读取处理
3.具体细节
主要用到了文件操作,用fopen打开mp3文件,用fread读取,记住fread读取是按字节的,也就是每次读取一个字节保存到数组。你可能还需要fseek来甚至从哪里读取信息。还有写函数fwrite。
还需要字符处理函数memcpy,strncmp,strcmp,ZeroMemory,strcpy等,记住声明的变量一定要初始化,尤其是数组和字符串变量。
音频除了mp3,还有aac wma等格式,这些里面也有变迁,但是和mp3的不一样。mp3里面除了ID3还有APE等标签,其格式也不同。不过大多数音频是mp3,用的是ID3
#include &stdio.h&
#include &stdlib.h&
#include &memory.h&
#include &math.h&
#define XMD_H
#include &jpeglib.h&
#include &setjmp.h&
#include &afxwin.h&
#include &Windows.h&
#include &initguid.h&
#include &ShlObj.h&
#pragma comment(lib, &jpeg.lib&)
//id3v2 标签头结构体
typedef struct
identi[3];//必须为ID3,否则认为标签不存在
//副版本号
size[4]; //标签大小,不包括标签头的10个字节
//标签帧头结构体
typedef struct
char FrameId[4];//标签帧标识符,用来表明这个标签帧的内容
byte size[4];
//此标签帧的大小,不包括此标签头的10个字节
byte flags[2];
char *MusicName=&Skylar Grey - I Love the way u lie.mp3&;
//char *MusicName=&home.mp3&;
long width = 0;
long height = 0;
FILE *OpenMusic(int &Len)
FILE *fp=NULL;
fp=fopen(MusicName,&rb&);
printf(&无法打开文件\n&);
//把打开的音乐文件流的内部指针重置到文件开头
fseek(fp,0,SEEK_SET);
//读取标签头
ID3V2Header mp3ID3V2;
ZeroMemory(&mp3ID3V2,10);
fread(&mp3ID3V2,10,1,fp);
//判断有没有id3v2的标签头
if(0!=strncmp(mp3ID3V2.identi,&ID3&,3))
printf(&没有ID2V2标签\n&);
fclose(fp);
//计算处整个标签的大小
Len = (mp3ID3V2.size[0]&0x7f)*0x200000
+(mp3ID3V2.size[1]&0x7f)*0x4000
+(mp3ID3V2.size[2]&0x7f)*0x80
+(mp3ID3V2.size[3]&0x7f);
BOOL GetPicInfo(FILE *fp, int &dwFrame, int Len, int &tempi)
ID3V2Frameheader pFrameB
ZeroMemory(&pFrameBuf,10);
fread(&pFrameBuf,10,1,fp);
//找到图片标签的所在位置
while((strncmp(pFrameBuf.FrameId,&APIC&,4) != 0))
//判断是否有图片
printf(&没有找到标识图像帧的标签\n&);
return FALSE;
dwFrame= pFrameBuf.size[0]*0x1000000
+pFrameBuf.size[1]*0x10000
+pFrameBuf.size[2]*0x100
+pFrameBuf.size[3];
fseek(fp,dwFrame,SEEK_CUR);
ZeroMemory(&pFrameBuf,10);
fread(&pFrameBuf,10,1,fp);
//计算出图片标签的大小
dwFrame= pFrameBuf.size[0]*0x1000000
+pFrameBuf.size[1]*0x10000
+pFrameBuf.size[2]*0x100
+pFrameBuf.size[3];
char image_tag[7]={&0&};
char pic_type[5]={&0&};
fread(image_tag,6,1,fp);
//判断图片格式
while(true)
if(i&dwFrame)
printf(&没有找到标识图像类型的标签\n&);
fclose(fp);
return FALSE;
if(0==(strcmp(image_tag,&image/&)))
fread(pic_type,4,1,fp);
//mp3里面大多图片都是jpeg,也是以jpeg作为标志的
//也有以jpe,jpg,peg作为标志的
//不过也有png等格式的。
if(0==strncmp(pic_type,&jpeg&,4))
else if(0==strncmp(pic_type,&jpg&,3))
fseek(fp,-1,SEEK_CUR);
else if(0==strncmp(pic_type,&peg&,3))
fseek(fp,-1,SEEK_CUR);
printf(&图片格式不是jpeg\n&);
fclose(fp);
return FALSE;
fseek(fp,-5,SEEK_CUR);
fread(image_tag,6,1,fp);
tempi=tempi+1;
return TRUE;
void GetPicRGB(FILE *fp, int dwFrame, int tempi)
TCHAR lpTempPathBuffer[MAX_PATH];
TCHAR szTempFileName[MAX_PATH];
DWORD dwRetVal=0;
UINT uRetVal=0;
unsigned char * bmpDataBuffer=NULL;
//这两个tag的是表明图片数据的开始
//jpeg图片开始的标志是0xFFD8
BYTE jpeg_header_tag1;
BYTE jpeg_header_tag2;
fseek(fp,0,SEEK_CUR);
fread(&jpeg_header_tag1,1,1,fp);
fseek(fp,0,SEEK_CUR);
fread(&jpeg_header_tag2,1,1,fp);
//计算出图片数据开始的地方
while(true)
if(i&dwFrame)
printf(&没有找到图像数据\n&);
fclose(fp);
bmpDataBuffer=NULL;
if((255==jpeg_header_tag1) && (216==jpeg_header_tag2))
pPicData = new BYTE[dwFrame-tempi];
ZeroMemory(pPicData,dwFrame-tempi);
//设定文件流的指针位置,并把图片的数据读入pPicData
fseek(fp,-2,SEEK_CUR);
fread(pPicData,dwFrame-tempi,1,fp);
fclose(fp);
fp=fopen(&temp.jpeg&,&w+b&);
fwrite(pPicData,dwFrame-tempi,1,fp);
delete []pPicD
DeleteFile(szTempFileName);
fseek(fp,-1,SEEK_CUR);
fread(&jpeg_header_tag1,1,1,fp);
fseek(fp,0,SEEK_CUR);
fread(&jpeg_header_tag2,1,1,fp);
struct jpeg_decompress_
struct jpeg_error_
cinfo.err = jpeg_std_error(&jerr);
jpeg_create_decompress(&cinfo);
fseek(fp,0,SEEK_SET);
jpeg_stdio_src(&cinfo,fp);
jpeg_read_header(&cinfo,1);
width = cinfo.image_
height = cinfo.image_
JSAMPARRAY
jpeg_start_decompress(&cinfo);
bmpDataBuffer=new unsigned char[width*height*3];
buffer=(*cinfo.mem-&alloc_sarray)
((j_common_ptr) &cinfo, JPOOL_IMAGE, (width*3), 1);
//获得图像rgb源数据,存入数组bmpDataBuffer
while(cinfo.output_scanline & cinfo.output_height)
jpeg_read_scanlines(&cinfo, buffer, 1);
if(cinfo.num_components==1)
//这个地方是把256转成24.我们得到的256的bmp图片,是在头信息的地方加了一个调色板
//调色板的大小是1024,是四个字节表示一种颜色,一共256种颜色
//256bmp下面不是rgb数据,是针对于调色板的一个索引,一个字节,8位,共可以表示2的8次方,也就是256种颜色
//如果num_componets=1也就表示是一种黑白的图片,黑白的图片的调色板的每种颜色的rgb是相等的,就是如果rgb相等
//显示出来的颜色是黑白的。这时我们可以用两种bmp来显示这个图片
//一个是256,调色板加索引数据
//另一种是24位图,24的bmp是没有调色板,后面3位表示一个颜色的rgb,所以是2^8*2^8*2^8,共可以表示2^24种颜色
//基于上面256灰度图的索引值就是rgb值,因为3个相等,所以可以把上面的256灰度的bmp去掉调色板,把每个索引用
//3位表示,值和索引一样,3个值也一样,这样就转成了一个24位的灰度图
for(j=0;j&j++)
bmpDataBuffer[(height - cinfo.output_scanline)*(width*3)+3*j] = buffer[0][j]; //R
bmpDataBuffer[(height - cinfo.output_scanline)*(width*3)+3*j+1] = buffer[0][j]; //G
bmpDataBuffer[(height - cinfo.output_scanline)*(width*3)+3*j+2] = buffer[0][j]; //B
if(cinfo.num_components==3)
for(j=0;j&(width*3);j++)
bmpDataBuffer[(height - cinfo.output_scanline)*(width*3)+j] = buffer[0][j+2]; //R
bmpDataBuffer[(height - cinfo.output_scanline)*(width*3)+j] = buffer[0][j]; //G
bmpDataBuffer[(height - cinfo.output_scanline)*(width*3)+j] = buffer[0][j-2]; //B
jpeg_finish_decompress(&cinfo);
jpeg_destroy_decompress(&cinfo);
//关闭临时文件指针,删除临时文件
fclose(fp);
remove(szTempFileName);
BITMAPFILEHEADER fileH
BITMAPINFOHEADER infoH
//bmp header(fileHeader)
ZeroMemory(&fileHeader, sizeof(BITMAPFILEHEADER));
fileHeader.bfType = 'MB';
fileHeader.bfSize = sizeof(BITMAPFILEHEADER)+ sizeof(BITMAPINFOHEADER) + (height * width * 3);
fileHeader.bfOffBits = sizeof(BITMAPFILEHEADER)+ sizeof(BITMAPINFOHEADER) ;
//bmp infoheader(infoHeader)
ZeroMemory(&infoHeader, sizeof(infoHeader));
infoHeader.biSize = sizeof(infoHeader);
infoHeader.biWidth =
infoHeader.biHeight =
infoHeader.biPlanes = 1;
infoHeader.biBitCount = 24;
infoHeader.biCompression = BI_RGB;
infoHeader.biSizeImage = width *
infoHeader.biXPelsPerMeter = 0;
infoHeader.biYPelsPerMeter = 0;
infoHeader.biClrUsed = 0;
infoHeader.biClrImportant = 0;
FILE *fpbmp=fopen(&a.bmp&,&w+b&);
fwrite(&fileHeader,sizeof(fileHeader),1,fpbmp);
fwrite(&infoHeader,sizeof(infoHeader),1,fpbmp);
fwrite(bmpDataBuffer,width*height*3,1,fpbmp);
fclose(fpbmp);
void jpgtobmp(const char *strSourceFileName, const char *strDestFileName)
BITMAPFILEHEADER
// bmp文件头
BITMAPINFOHEADER
// bmp头信息
RGBQUAD rq[256];
int nA // 用于字节对齐
char indata[1000000]; // 用于存放解压缩前的图像数据,该数据直接从jpg文件读取
BYTE *data= NULL;
int nComponent = 0;
// 声明解压缩对象及错误信息管理器
struct jpeg_decompress_
struct jpeg_error_
cinfo.err = jpeg_std_error(&jerr);
jpeg_create_decompress(&cinfo);
FILE *f = fopen(strSourceFileName,&rb&);
if (f==NULL)
printf(&Open file error!\n&);
// 下面代码用于解压缩,从本行开始解压缩
jpeg_stdio_src(&cinfo, f );
jpeg_read_header(&cinfo, TRUE);
nAdjust = cinfo.image_width*cinfo.num_components%4;
if (nAdjust) nAdjust = 4-nA
data = new BYTE[(cinfo.image_width*cinfo.num_components+nAdjust)*cinfo.image_height];
jpeg_start_decompress(&cinfo);
JSAMPROW row_pointer[1];
while (cinfo.output_scanline & cinfo.output_height)
row_pointer[0] = &data[(cinfo.output_height - cinfo.output_scanline-1)*(cinfo.image_width*cinfo.num_components+nAdjust)];
jpeg_read_scanlines(&cinfo,row_pointer ,
jpeg_finish_decompress(&cinfo);
jpeg_destroy_decompress(&cinfo);
// 上面代码用于解压缩,到本行为止解压缩完成
fclose(f);
// 以下代码讲解压缩后的图像存入文件,可以根据实际应用做其他处理,如传输
f=fopen(strDestFileName,&wb&);
if (f==NULL)
//delete [] pDataC
// 写文件头
memset(&bfh,0,sizeof(bfh));
bfh.bfSize = sizeof(bfh)+sizeof(bih);
bfh.bfOffBits = sizeof(bfh)+sizeof(bih);
if (cinfo.num_components==1)
bfh.bfOffBits += 1024;
bfh.bfSize += 1024;
bfh.bfSize += (cinfo.image_width*cinfo.num_components+nAdjust)*cinfo.image_
bfh.bfType = 0x4d42;
fwrite(&bfh,sizeof(bfh),1,f);
// 写图像信息
bih.biBitCount = cinfo.num_components*8;
bih.biSize = sizeof(bih);
bih.biWidth = cinfo.image_
bih.biHeight = cinfo.image_
bih.biPlanes = 1;
bih.biCompression = 0;
bih.biSizeImage = (cinfo.image_width*cinfo.num_components+nAdjust)*cinfo.image_
bih.biXPelsPerMeter = 0;
bih.biYPelsPerMeter = 0;
bih.biClrUsed = 0;
bih.biClrImportant = 0;
fwrite(&bih,sizeof(bih),1,f);
// 写调色板
if (cinfo.num_components ==1)
for (int i=0;i&256;i++)
rq[i].rgbBlue =i;
rq[i].rgbGreen =
rq[i].rgbRed =
rq[i].rgbReserved = 0;
fwrite(rq,1024,1,f);
if (cinfo.num_components==3)
// 调整rgb顺序
for (int j=0;j&bih.biHj++)
for (int i = 0;i&bih.biWi++)
BYTE red = data[j*(cinfo.image_width*cinfo.num_components+nAdjust)+i*3];
data[j*(cinfo.image_width*cinfo.num_components+nAdjust)+i*3] = data[j*(cinfo.image_width*cinfo.num_components+nAdjust)+i*3+2];
data[j*(cinfo.image_width*cinfo.num_components+nAdjust)+i*3+2] =
fwrite(data,(cinfo.image_width*cinfo.num_components+nAdjust)*cinfo.image_height,1,f);
fclose(f);
void jpgtobmp1(const char *strSourceFileName, const char *strDestFileName)
BITMAPFILEHEADER
// bmp文件头
BITMAPINFOHEADER
// bmp头信息
RGBQUAD rq[256];
int nA // 用于字节对齐
char indata[1000000]; // 用于存放解压缩前的图像数据,该数据直接从jpg文件读取
BYTE *data= NULL;
BYTE *data1=NULL;
int nComponent = 3;
// 声明解压缩对象及错误信息管理器
struct jpeg_decompress_
struct jpeg_error_
cinfo.err = jpeg_std_error(&jerr);
jpeg_create_decompress(&cinfo);
FILE *f = fopen(strSourceFileName,&rb&);
if (f==NULL)
printf(&Open file error!\n&);
// 下面代码用于解压缩,从本行开始解压缩
jpeg_stdio_src(&cinfo, f );
jpeg_read_header(&cinfo, TRUE);
nAdjust = cinfo.image_width*cinfo.num_components%4;
if (nAdjust) nAdjust = 4-nA
just = cinfo.image_width*nComponent%4;
if (just) just = 4-
data = new BYTE[(cinfo.image_width*cinfo.num_components+nAdjust)*cinfo.image_height];
data1=new BYTE[(cinfo.image_width*nComponent+just)*cinfo.image_height];
jpeg_start_decompress(&cinfo);
JSAMPROW row_pointer[1];
while (cinfo.output_scanline & cinfo.output_height)
row_pointer[0] = &data[(cinfo.output_height - cinfo.output_scanline-1)*(cinfo.image_width*cinfo.num_components+nAdjust)];
jpeg_read_scanlines(&cinfo,row_pointer ,
jpeg_finish_decompress(&cinfo);
jpeg_destroy_decompress(&cinfo);
// 上面代码用于解压缩,到本行为止解压缩完成
fclose(f);
// 以下代码讲解压缩后的图像存入文件,可以根据实际应用做其他处理,如传输
f=fopen(strDestFileName,&wb&);
if (f==NULL)
//delete [] pDataC
// 写文件头
memset(&bfh,0,sizeof(bfh));
bfh.bfSize = sizeof(bfh)+sizeof(bih);
bfh.bfOffBits = sizeof(bfh)+sizeof(bih);
bfh.bfSize += (cinfo.image_width*nComponent+just)*cinfo.image_
bfh.bfType = 0x4d42;
fwrite(&bfh,sizeof(bfh),1,f);
// 写图像信息
bih.biBitCount = nComponent*8;
bih.biSize = sizeof(bih);
bih.biWidth = cinfo.image_
bih.biHeight = cinfo.image_
bih.biPlanes = 1;
bih.biCompression = 0;
bih.biSizeImage = (cinfo.image_width*nComponent+just)*cinfo.image_
bih.biXPelsPerMeter = 0;
bih.biYPelsPerMeter = 0;
bih.biClrUsed = 0;
bih.biClrImportant = 0;
fwrite(&bih,sizeof(bih),1,f);
for(int testi=0; testi&((cinfo.image_width*cinfo.num_components+nAdjust)*cinfo.image_height); testi++)
data1[testi*3]=data[testi];
data1[testi*3+1]=data[testi];
data1[testi*3+2]=data[testi];
fwrite(data1,(cinfo.image_width*nComponent+just)*cinfo.image_height,1,f);
fclose(f);
int main()
FILE *fp=NULL;
int Len=0;
fp=OpenMusic(Len);
if(NULL==fp)
//图片帧大小
int dwFrame=0;
//记录图片标签数据中不是图片数据的字节数
int tempi=0;
if(FALSE==GetPicInfo(fp,dwFrame,Len,tempi))
//获取图片数据
GetPicRGB(fp,dwFrame,tempi);
jpgtobmp(&temp.jpeg&,&b.bmp&);
jpgtobmp1(&temp.jpeg&,&c.bmp&);
&&相关文章推荐
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:58258次
排名:千里之外
转载:61篇
(1)(7)(7)(4)(16)(4)(14)(3)(1)(7)
(window.slotbydup = window.slotbydup || []).push({
id: '4740881',
container: s,
size: '200,200',
display: 'inlay-fix'

我要回帖

更多关于 hyperv如何删除虚拟机 的文章

 

随机推荐