使用ffmpeg将BMP图片编码为x264视频文件,将H264视频保存为BMP图片,yuv视频文件保存为图片的代码
ffmpeg开源库,实现将bmp格式的图片编码成x264文件,并将编码好的H264文件解码保存为BMP文件。
实现将视频文件yuv格式保存的图片格式的測试,图像格式png,jpg, gif等等測试均OK
自己依据博客的代码,vs2010搭建的測试环境。资源下载
详细代码:
#define _AFXDLL
#include<afxwin.h>
#ifdef __cplusplus
extern "C" {
#endif
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
#include <libswscale/swscale.h>
void main()
{
CFile file[5];
BYTE *szTxt[5];
int nWidth = 0;
int nHeight= 0;
int nDataLen=0;
int nLen;
CString csFileName;
for (int fileI = 1; fileI <= 5; fileI ++)
{
csFileName.Format("%d.bmp", fileI);
file[fileI - 1].Open(csFileName,CFile::modeRead | CFile::typeBinary);
nLen = file[fileI - 1].GetLength();
szTxt[fileI -1] = new BYTE[nLen];
file[fileI - 1].Read(szTxt[fileI - 1], nLen);
file[fileI - 1].Close();
//BMP bmi;//BITMAPINFO bmi;
//int nHeadLen = sizeof(BMP);
BITMAPFILEHEADER bmpFHeader;
BITMAPINFOHEADER bmpIHeader;
memcpy(&bmpFHeader,szTxt[fileI -1],sizeof(BITMAPFILEHEADER));
int nHeadLen = bmpFHeader.bfOffBits - sizeof(BITMAPFILEHEADER);
memcpy(&bmpIHeader,szTxt[fileI - 1]+sizeof(BITMAPFILEHEADER),nHeadLen);
nWidth = bmpIHeader.biWidth;// 464;// bmi.bmpInfo.bmiHeader.biWidth;// ;
nHeight = bmpIHeader.biHeight;//362;// bmi.bmpInfo.bmiHeader.biHeight;// ;
szTxt[fileI - 1] += bmpFHeader.bfOffBits;
nDataLen = nLen-bmpFHeader.bfOffBits;
}
getchar();
av_register_all();
avcodec_register_all();
AVFrame *m_pRGBFrame = new AVFrame[1]; //RGB帧数据
AVFrame *m_pYUVFrame = new AVFrame[1];; //YUV帧数据
AVCodecContext *c= NULL;
AVCodecContext *in_c= NULL;
AVCodec *pCodecH264; //编码器
uint8_t * yuv_buff;//
//查找h264编码器
pCodecH264 = avcodec_find_encoder(CODEC_ID_H264);
if(!pCodecH264)
{
fprintf(stderr, "h264 codec not found\n");
getchar();
exit(1);
}
c= avcodec_alloc_context3(pCodecH264);
c->bit_rate = 3000000;// put sample parameters
c->width =nWidth;//
c->height = nHeight;//
// frames per second
AVRational rate;
rate.num = 1;
rate.den = 25;
c->time_base= rate;//(AVRational){1,25};
c->gop_size = 10; // emit one intra frame every ten frames
c->max_b_frames=1;
c->thread_count = 1;
c->pix_fmt = PIX_FMT_YUV420P;//PIX_FMT_RGB24;
//av_opt_set(c->priv_data, /*"preset"*/"libvpx-1080p.ffpreset", /*"slow"*/NULL, 0);
//打开编码器
if(avcodec_open2(c,pCodecH264,NULL)<0){
printf("avcodec_open2 failed\n");
TRACE("不能打开编码库");
getchar();
}
int size = c->width * c->height;
yuv_buff = (uint8_t *) malloc((size * 3) / 2); // size for YUV 420
//将rgb图像数据填充rgb帧
uint8_t * rgb_buff = new uint8_t[nDataLen];
//图象编码 outbuf_size太小会报错,图像清晰度也会差
int outbuf_size = 900000;
uint8_t * outbuf= (uint8_t*)malloc(outbuf_size);
int u_size = 0;
FILE *f=NULL;
char * filename = "myData.h264";
f = fopen(filename, "wb");
if (!f)
{
TRACE( "could not open %s\n", filename);
getchar();
exit(1);
}
//初始化SwsContext
SwsContext * scxt = sws_getContext(c->width,c->height,PIX_FMT_BGR24,c->width,c->height,PIX_FMT_YUV420P,SWS_POINT,NULL,NULL,NULL);
AVPacket avpkt;
//AVFrame *pTFrame=new AVFrame
for (int i=0;i<250;++i)
{
//AVFrame *m_pYUVFrame = new AVFrame[1];
int index = (i / 25) % 5;
memcpy(rgb_buff,szTxt[index],nDataLen);
avpicture_fill((AVPicture*)m_pRGBFrame, (uint8_t*)rgb_buff, PIX_FMT_RGB24, nWidth, nHeight);
//将YUV buffer 填充YUV Frame
avpicture_fill((AVPicture*)m_pYUVFrame, (uint8_t*)yuv_buff, PIX_FMT_YUV420P, nWidth, nHeight);
// 翻转RGB图像
m_pRGBFrame->data[0] += m_pRGBFrame->linesize[0] * (nHeight - 1);
m_pRGBFrame->linesize[0] *= -1;
m_pRGBFrame->data[1] += m_pRGBFrame->linesize[1] * (nHeight / 2 - 1);
m_pRGBFrame->linesize[1] *= -1;
m_pRGBFrame->data[2] += m_pRGBFrame->linesize[2] * (nHeight / 2 - 1);
m_pRGBFrame->linesize[2] *= -1;
//将RGB转化为YUV
sws_scale(scxt,m_pRGBFrame->data,m_pRGBFrame->linesize,0,c->height,m_pYUVFrame->data,m_pYUVFrame->linesize);
static int got_packet_ptr = 0;
av_init_packet(&avpkt);
avpkt.data = outbuf;
avpkt.size = outbuf_size;
u_size = avcodec_encode_video2(c, &avpkt, m_pYUVFrame, &got_packet_ptr);
m_pYUVFrame->pts++;
if (u_size == 0)
{
fwrite(avpkt.data, 1, avpkt.size, f);
}
}
fclose(f);
delete []m_pRGBFrame;
delete []m_pYUVFrame;
delete []rgb_buff;
free(outbuf);
avcodec_close(c);
av_free(c);
}
#ifdef __cplusplus
}
#endif
#include<afxwin.h>
#ifdef __cplusplus
extern "C" {
#endif #include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
#include <libswscale/swscale.h>
void main()
{
CFile file[5];
BYTE *szTxt[5]; int nWidth = 0;
int nHeight= 0; int nDataLen=0; int nLen; CString csFileName;
for (int fileI = 1; fileI <= 5; fileI ++)
{
csFileName.Format("%d.bmp", fileI);
file[fileI - 1].Open(csFileName,CFile::modeRead | CFile::typeBinary);
nLen = file[fileI - 1].GetLength(); szTxt[fileI -1] = new BYTE[nLen];
file[fileI - 1].Read(szTxt[fileI - 1], nLen);
file[fileI - 1].Close(); //BMP bmi;//BITMAPINFO bmi;
//int nHeadLen = sizeof(BMP);
BITMAPFILEHEADER bmpFHeader;
BITMAPINFOHEADER bmpIHeader;
memcpy(&bmpFHeader,szTxt[fileI -1],sizeof(BITMAPFILEHEADER)); int nHeadLen = bmpFHeader.bfOffBits - sizeof(BITMAPFILEHEADER);
memcpy(&bmpIHeader,szTxt[fileI - 1]+sizeof(BITMAPFILEHEADER),nHeadLen); nWidth = bmpIHeader.biWidth;// 464;// bmi.bmpInfo.bmiHeader.biWidth;// ;
nHeight = bmpIHeader.biHeight;//362;// bmi.bmpInfo.bmiHeader.biHeight;// ; szTxt[fileI - 1] += bmpFHeader.bfOffBits;
nDataLen = nLen-bmpFHeader.bfOffBits;
}
getchar();
av_register_all();
avcodec_register_all();
AVFrame *m_pRGBFrame = new AVFrame[1]; //RGB帧数据
AVFrame *m_pYUVFrame = new AVFrame[1];; //YUV帧数据
AVCodecContext *c= NULL;
AVCodecContext *in_c= NULL;
AVCodec *pCodecH264; //编码器
uint8_t * yuv_buff;// //查找h264编码器
pCodecH264 = avcodec_find_encoder(CODEC_ID_H264);
if(!pCodecH264)
{
fprintf(stderr, "h264 codec not found\n");
getchar();
exit(1);
} c= avcodec_alloc_context3(pCodecH264);
c->bit_rate = 3000000;// put sample parameters
c->width =nWidth;//
c->height = nHeight;// // frames per second
AVRational rate;
rate.num = 1;
rate.den = 25;
c->time_base= rate;//(AVRational){1,25};
c->gop_size = 10; // emit one intra frame every ten frames
c->max_b_frames=1;
c->thread_count = 1;
c->pix_fmt = PIX_FMT_YUV420P;//PIX_FMT_RGB24; //av_opt_set(c->priv_data, /*"preset"*/"libvpx-1080p.ffpreset", /*"slow"*/NULL, 0);
//打开编码器
if(avcodec_open2(c,pCodecH264,NULL)<0){
printf("avcodec_open2 failed\n");
TRACE("不能打开编码库");
getchar();
} int size = c->width * c->height; yuv_buff = (uint8_t *) malloc((size * 3) / 2); // size for YUV 420 //将rgb图像数据填充rgb帧
uint8_t * rgb_buff = new uint8_t[nDataLen]; //图象编码 outbuf_size太小会报错,图像清晰度也会差
int outbuf_size = 900000;
uint8_t * outbuf= (uint8_t*)malloc(outbuf_size);
int u_size = 0;
FILE *f=NULL;
char * filename = "myData.h264";
f = fopen(filename, "wb");
if (!f)
{
TRACE( "could not open %s\n", filename);
getchar();
exit(1);
} //初始化SwsContext
SwsContext * scxt = sws_getContext(c->width,c->height,PIX_FMT_BGR24,c->width,c->height,PIX_FMT_YUV420P,SWS_POINT,NULL,NULL,NULL); AVPacket avpkt; //AVFrame *pTFrame=new AVFrame
for (int i=0;i<250;++i)
{ //AVFrame *m_pYUVFrame = new AVFrame[1]; int index = (i / 25) % 5;
memcpy(rgb_buff,szTxt[index],nDataLen); avpicture_fill((AVPicture*)m_pRGBFrame, (uint8_t*)rgb_buff, PIX_FMT_RGB24, nWidth, nHeight); //将YUV buffer 填充YUV Frame
avpicture_fill((AVPicture*)m_pYUVFrame, (uint8_t*)yuv_buff, PIX_FMT_YUV420P, nWidth, nHeight); // 翻转RGB图像
m_pRGBFrame->data[0] += m_pRGBFrame->linesize[0] * (nHeight - 1);
m_pRGBFrame->linesize[0] *= -1;
m_pRGBFrame->data[1] += m_pRGBFrame->linesize[1] * (nHeight / 2 - 1);
m_pRGBFrame->linesize[1] *= -1;
m_pRGBFrame->data[2] += m_pRGBFrame->linesize[2] * (nHeight / 2 - 1);
m_pRGBFrame->linesize[2] *= -1; //将RGB转化为YUV
sws_scale(scxt,m_pRGBFrame->data,m_pRGBFrame->linesize,0,c->height,m_pYUVFrame->data,m_pYUVFrame->linesize); static int got_packet_ptr = 0;
av_init_packet(&avpkt);
avpkt.data = outbuf;
avpkt.size = outbuf_size;
u_size = avcodec_encode_video2(c, &avpkt, m_pYUVFrame, &got_packet_ptr);
m_pYUVFrame->pts++;
if (u_size == 0)
{
fwrite(avpkt.data, 1, avpkt.size, f);
}
} fclose(f);
delete []m_pRGBFrame;
delete []m_pYUVFrame;
delete []rgb_buff;
free(outbuf);
avcodec_close(c);
av_free(c); } #ifdef __cplusplus
}
#endif
全然依照博客中的代码測试发现会报以下的信息,并且在播放过程中,画面都是模糊的。改动了outbuff_size的大小攻克了这个问题。
疑问:为什么要循环250次?有知道麻烦解答下!
for (int i=0;i<250;++i)
将H264视频保存为BMP图片,详细代码例如以下:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <windows.h> #ifdef __cplusplus
extern "C" {
#endif #include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
#include <libswscale/swscale.h> void SaveAsBMP (AVFrame *pFrameRGB, int width, int height, int index, int bpp)
{
char buf[5] = {0};
BITMAPFILEHEADER bmpheader;
BITMAPINFOHEADER bmpinfo;
FILE *fp; char filename[20] = "";
_itoa (index, buf, 10);
strcat (filename, buf);
strcat (filename, ".bmp"); if ( (fp = fopen(filename,"wb+")) == NULL )
{
printf ("open file failed!\n");
return;
} bmpheader.bfType = 0x4d42;
bmpheader.bfReserved1 = 0;
bmpheader.bfReserved2 = 0;
bmpheader.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
bmpheader.bfSize = bmpheader.bfOffBits + width*height*bpp/8; bmpinfo.biSize = sizeof(BITMAPINFOHEADER);
bmpinfo.biWidth = width;
bmpinfo.biHeight = height;
bmpinfo.biPlanes = 1;
bmpinfo.biBitCount = bpp;
bmpinfo.biCompression = BI_RGB;
bmpinfo.biSizeImage = (width*bpp+31)/32*4*height;
bmpinfo.biXPelsPerMeter = 100;
bmpinfo.biYPelsPerMeter = 100;
bmpinfo.biClrUsed = 0;
bmpinfo.biClrImportant = 0; fwrite (&bmpheader, sizeof(bmpheader), 1, fp);
fwrite (&bmpinfo, sizeof(bmpinfo), 1, fp);
fwrite (pFrameRGB->data[0], width*height*bpp/8, 1, fp); fclose(fp);
} int main (void)
{
unsigned int i = 0, videoStream = -1;
AVCodecContext *pCodecCtx;
AVFormatContext *pFormatCtx = NULL;
AVCodec *pCodec;
AVFrame *pFrame, *pFrameRGB;
struct SwsContext *pSwsCtx;
const char *filename = "myData.h264";
AVPacket packet;
int frameFinished;
int PictureSize;
uint8_t *buf; av_register_all(); if (avformat_open_input(&pFormatCtx, filename, NULL, NULL) != 0 ){
printf ("av open input file failed!\n");
exit (1);
} if ( avformat_find_stream_info(pFormatCtx,NULL) < 0 ){
printf ("av find stream info failed!\n");
exit (1);
} for ( i=0; i<pFormatCtx->nb_streams; i++ ){
if ( pFormatCtx->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO ){
videoStream = i;
break;
}
} if (videoStream == -1){
printf ("find video stream failed!\n");
exit (1);
} pCodecCtx = pFormatCtx->streams[videoStream]->codec; pCodec = avcodec_find_decoder (pCodecCtx->codec_id);
if (pCodec == NULL){
printf ("avcode find decoder failed!\n");
exit (1);
} if ( avcodec_open2(pCodecCtx, pCodec,NULL)<0 ){
printf ("avcode open failed!\n");
exit (1);
} pFrame = avcodec_alloc_frame();
pFrameRGB = avcodec_alloc_frame(); if ( (pFrame == NULL)||(pFrameRGB == NULL) ){
printf("avcodec alloc frame failed!\n");
exit (1);
} PictureSize = avpicture_get_size (PIX_FMT_BGR24, pCodecCtx->width, pCodecCtx->height); buf = (uint8_t *)av_malloc(PictureSize); if ( buf == NULL ){
printf( "av malloc failed!\n");
exit(1);
} avpicture_fill ( (AVPicture *)pFrameRGB, buf, PIX_FMT_BGR24, pCodecCtx->width, pCodecCtx->height); pSwsCtx = sws_getContext (pCodecCtx->width,
pCodecCtx->height,
pCodecCtx->pix_fmt,
pCodecCtx->width,
pCodecCtx->height,
PIX_FMT_BGR24,
SWS_BICUBIC,
NULL, NULL, NULL); i = 0; while(av_read_frame(pFormatCtx, &packet) >= 0){
if(packet.stream_index == videoStream){
avcodec_decode_video2(pCodecCtx, pFrame, &frameFinished, &packet); if(frameFinished){
//反转图像
pFrame->data[0] += pFrame->linesize[0] * (pCodecCtx->height - 1);
pFrame->linesize[0] *= -1;
pFrame->data[1] += pFrame->linesize[1] * (pCodecCtx->height / 2 - 1);
pFrame->linesize[1] *= -1;
pFrame->data[2] += pFrame->linesize[2] * (pCodecCtx->height / 2 - 1);
pFrame->linesize[2] *= -1; sws_scale (pSwsCtx, pFrame->data, pFrame->linesize, 0, pCodecCtx->height, pFrameRGB->data, pFrameRGB->linesize); SaveAsBMP (pFrameRGB, pCodecCtx->width, pCodecCtx->height, i++, 24);
}
}
av_free_packet(&packet);
} while(1){
packet.data = NULL;
packet.size = 0;
avcodec_decode_video2(pCodecCtx, pFrame, &frameFinished, &packet); if(frameFinished){
//反转图像
pFrame->data[0] += pFrame->linesize[0] * (pCodecCtx->height - 1);
pFrame->linesize[0] *= -1;
pFrame->data[1] += pFrame->linesize[1] * (pCodecCtx->height / 2 - 1);
pFrame->linesize[1] *= -1;
pFrame->data[2] += pFrame->linesize[2] * (pCodecCtx->height / 2 - 1);
pFrame->linesize[2] *= -1; sws_scale (pSwsCtx, pFrame->data, pFrame->linesize, 0, pCodecCtx->height, pFrameRGB->data, pFrameRGB->linesize); SaveAsBMP (pFrameRGB, pCodecCtx->width, pCodecCtx->height, i++, 24);
}else{
break;
} av_free_packet(&packet);
} sws_freeContext (pSwsCtx);
av_free (pFrame);
av_free (pFrameRGB);
avcodec_close (pCodecCtx);
avformat_close_input (&pFormatCtx); return 0;
} #ifdef __cplusplus
}
#endif
视频文件保存图片的另外一个方法,看代码
/*File : yuv2pic
*Auth : sjin
*Date : 20141123
*Mail : 413977243@qq.com
*/ /*
* 參考博客http://blog.csdn.net/leixiaohua1020/article/details/25346147
*本程序实现了YUV420P像素数据编码为JPEG图片。是最简单的FFmpeg编码方面的教程。
*通过学习本样例能够了解FFmpeg的编码流程。
*/
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
#include <libswscale/swscale.h> #define INPUT_FILE_NAME "yuv420p.yuv"
#define OUTPUT_FILE_NAME "encode.png"
#define INPUT_FILE_WDITH 176
#define INPUT_FILE_HEIGHT 144 int main(int argc, char* argv[])
{
AVFormatContext* pFormatCtx;
AVOutputFormat* fmt;
AVStream* video_st;
AVCodecContext* pCodecCtx;
AVCodec* pCodec; uint8_t* picture_buf;
AVFrame* picture;
int size; FILE *in_file = fopen(INPUT_FILE_NAME, "rb"); //视频YUV源文件
int in_w = INPUT_FILE_WDITH;
int in_h = INPUT_FILE_HEIGHT; //宽高
const char* out_file = OUTPUT_FILE_NAME; //输出文件路径 av_register_all();
#if 0
//方法1.组合使用几个函数
pFormatCtx = avformat_alloc_context();
//猜格式。用MJPEG编码
fmt = av_guess_format("mjpeg", NULL, NULL);
pFormatCtx->oformat = fmt;
//注意:输出路径
if (avio_open(&pFormatCtx->pb,out_file, AVIO_FLAG_READ_WRITE) < 0){
printf("输出文件打开失败");
return -1;
}
#else
//方法2.更加自己主动化一些
//分配一个输出(out_file)文件格式的AVFormatContext的上下文句柄
avformat_alloc_output_context2(&pFormatCtx, NULL, NULL, out_file);
fmt = pFormatCtx->oformat; video_st = avformat_new_stream(pFormatCtx,NULL);
if (video_st==NULL){
return -1;
}
#endif
pCodecCtx = video_st->codec;
pCodecCtx->codec_id = fmt->video_codec;
pCodecCtx->codec_type = AVMEDIA_TYPE_VIDEO;
pCodecCtx->pix_fmt = PIX_FMT_YUVJ420P; pCodecCtx->width = in_w;
pCodecCtx->height = in_h; pCodecCtx->time_base.num = 1;
pCodecCtx->time_base.den = 25;
//输出格式信息
av_dump_format(pFormatCtx, 0, out_file, 1); pCodec = avcodec_find_encoder(pCodecCtx->codec_id);
if (!pCodec){
printf("没有找到合适的编码器!");
return -1;
}
if (avcodec_open2(pCodecCtx, pCodec,NULL) < 0){
printf("编码器打开失败!");
return -1;
} //申请解码后保存视频帧的空间,AVFrame结构体
picture = avcodec_alloc_frame();
//即使我们申请的一帧的内存,当转换的时候,我们仍须要内存去保存原始的数据
//利用以下的函数来获得原始数据帧的大小,手动分配内存
size = avpicture_get_size(pCodecCtx->pix_fmt, pCodecCtx->width, pCodecCtx->height);
picture_buf = (uint8_t *)av_malloc(size);
if (!picture_buf){
return -1;
}
//设置指定图像的參数,并指着图像数据缓冲区
avpicture_fill((AVPicture *)picture, picture_buf, pCodecCtx->pix_fmt, pCodecCtx->width, pCodecCtx->height); //写文件头
avformat_write_header(pFormatCtx,NULL); AVPacket pkt;
int y_size = pCodecCtx->width * pCodecCtx->height;
av_new_packet(&pkt,y_size*3);
//读入YUV
if (fread(picture_buf, 1, y_size*3/2, in_file) < 0){
printf("文件读取错误");
return -1;
} //翻转图像
picture->data[0] = picture_buf; // 亮度Y
picture->data[1] = picture_buf+ y_size; // U
picture->data[2] = picture_buf+ y_size*5/4; // V
int got_picture=0;
//编码
int ret = avcodec_encode_video2(pCodecCtx, &pkt,picture, &got_picture);
if(ret < 0){
printf("编码错误!\n");
return -1;
}
if (got_picture==1){
pkt.stream_index = video_st->index;
ret = av_write_frame(pFormatCtx, &pkt);
} av_free_packet(&pkt);
//写文件尾
av_write_trailer(pFormatCtx); printf("编码成功!\n"); if (video_st){
avcodec_close(video_st->codec);
av_free(picture);
av_free(picture_buf);
} avio_close(pFormatCtx->pb);
avformat_free_context(pFormatCtx); fclose(in_file); return 0;
}
以下是编译的时候,比較好用的Makefile文件
# use pkg-config for getting CFLAGS and LDLIBS
FFMPEG_LIBS= libavdevice \
libavformat \
libavfilter \
libavcodec \
libswresample \
libswscale \
libavutil \ CFLAGS += -Wall -O2 -g
CFLAGS := $(shell pkg-config --cflags $(FFMPEG_LIBS)) $(CFLAGS)
LDLIBS := $(shell pkg-config --libs $(FFMPEG_LIBS)) $(LDLIBS) EXAMPLES= yuv2pic OBJS=$(addsuffix .o,$(EXAMPLES)) # the following examples make explicit use of the math library
LDLIBS += -lx264 -m32 -pthread -lm -ldl .phony:all clean all: $(OBJS) $(EXAMPLES) clean:
rm $(EXAMPLES) $(OBJS)
使用ffmpeg将BMP图片编码为x264视频文件,将H264视频保存为BMP图片,yuv视频文件保存为图片的代码的更多相关文章
- FFmpeg YUV视频序列编码为视频
上一篇已经写了如何配置好开发环境,这次就先小试牛刀,来个视频的编码.搞视频处理的朋友肯定比较熟悉YUV视频序列,很多测试库提供的视频数据都是YUV视频序列,我们这里就用用YUV视频序列来做视频.关于Y ...
- Base64图片编码原理,base64图片工具介绍,图片在线转换Base64
Base64图片编码原理,base64图片工具介绍,图片在线转换Base64 DataURI 允许在HTML文档中嵌入小文件,可以使用 img 标签或 CSS 嵌入转换后的 Base64 编码,减少 ...
- FFmpeg源码结构图 - 编码
===================================================== FFmpeg的库函数源码分析文章列表: [架构图] FFmpeg源码结构图 - 解码 FFm ...
- Base64图片编码的使用
一.base64编码介绍 Base64是网络上最常见的用于传输8Bit字节代码的编码方式之一,Base64编码可用于在HTTP环境下传递较长的标识信息.采用Base64编码具有不可读性,即所编码的数据 ...
- 【VC++技术杂谈006】截取电脑桌面并将其保存为bmp图片
本文主要介绍如何截取电脑桌面并将其保存为bmp图片. 1. Bmp图像文件组成 Bmp是Windows操作系统中的标准图像文件格式. Bmp图像文件由四部分组成: (1)位图头文件数据结构,包含Bmp ...
- 杂谈SharpDx中的WIC组件——我们需要WIC的图片编码功能么?
在前文 SharpDX之Direct2D教程II——加载位图文件和保存位图文件 中,发现在VB2010中不能很好的运用SharpDx中的WIC组件进行图片的编码工作.可能是我的设置问题,也可能是Sha ...
- android 开发 对图片编码,并生成gif图片
demo场景: 将2张静态的png格式图片组合生成一个gif图片,间隔500毫秒,关键类:AnimatedGifEncoder 如需要解析gif获取每帧的图片,可参考上一篇博客:<android ...
- [转]RGB数据保存为BMP图片
转自:http://blog.csdn.net/yixianfeng41/article/details/52591585 一.BMP文件由文件头.位图信息头.颜色信息和图形数据四部分组成. 1.BM ...
- base64图片编码大小与原图文件大小之间的联系
base64图片编码大小与原图文件大小之间的联系 有时候我们需要把canvas画布的图画转换成图片输出页面,而用canvas生成的图片就是base64编码的,它是由数字.字母等一大串的字符组成的,但是 ...
随机推荐
- Java之旅(一)---说说“异常”那些事
从開始学习VB,就听说过"异常",认为异常处理就是加上try..catch,不让错误抛出给用户,到此为止,不要再往下问了,再问也不会了.这就是那时候的理解.如今随时项目经验的 ...
- NS2 nam中节点及数据流颜色设置
NS2 节点颜色设置在http://hi.baidu.com/jrwen0/item/d105c642f4c3ce36fb89601b说明的比較具体,大家能够參见. 我这里想说的是数据流颜色的设置,相 ...
- 各浏览器对 window.open() 的窗口特征 sFeatures 参数支持程度存在差异
标准参考 无. 问题描述 使用 window.open 方法可以弹出一个新窗口,其中 open 方法的 sFeatures 参数选项在各浏览器中支持程度不一,这有可能导致同样的代码使各浏览器中弹出窗口 ...
- C#中接口和方法的运用(Fourteenth Day)
由于周五我有一些事情没来得及总结当天的知识,所以在今天总结一下周五在云和学院所学到的有关接口和方法的知识. 理论: 接口: •接口的定义:interface关键字,接口中可以有属性.方法(未实现) • ...
- Cocos2d-x win7 + vs2010 配置图文详解(亲测)
下载最新版的cocos2d-x.打开浏览器,输入cocos2d-x.org,然后选择Download,本教程写作时最新版本为cocos2d-1.01-x-0.9.1,具体下载位置如下图: 下载完之后, ...
- java集群
java集群 分类: java学习2011-05-12 09:12 7531人阅读 评论(9) 收藏 举报 java服务器负载均衡ejb集群数据库 序言 越来越多的关键应用运行在J2EE(Java 2 ...
- php随笔3-thinkphp 学习-ThinkPHP3.1快速入门(1)基础
ThinkPHP3.1快速入门(1)基础 简介 ThinkPHP是一个快速.简单的基于MVC和面向对象的轻量级PHP开发 框架,遵循Apache2开源协议发布,从诞生以来一直秉承简洁实用的设计原则,在 ...
- ioctl函数详细说明
本函数影响由fd 参数引用的一个打开的文件. #include<unistd.h> int ioctl( int fd, int request, .../* void *arg */ ) ...
- [置顶] High Performance Canvas Game for Android
Rule #0 为移动平台进行优化 为移动平台进行优化是十分重要的,因为移动平台的性能大概只有桌面平台的1/10左右(*1),它通常意味着: 更慢的CPU速度,这意味着不经过优化的JavaScript ...
- BZOJ 1610: [Usaco2008 Feb]Line连线游戏
1610: [Usaco2008 Feb]Line连线游戏 Description Farmer John最近发明了一个游戏,来考验自命不凡的贝茜.游戏开始的时 候,FJ会给贝茜一块画着N (2 &l ...