控制台下播放bad apple by C

来源:互联网 发布:同花顺数据库要钱吗 编辑:程序博客网 时间:2024/05/16 06:09

最近在b站看到有人上传了控制台下播放bad apple的视频(别人真有创意啊T-T),觉得很有趣,于是自己便做了一下。

原理其实很简单,大概分三步:

1.把准备好的视频用软件把它的每帧都截出来;我用Free Video to JPG Converter

2.把截出来的每张图用软件把它转换成字符画;注意宽高比!!!我用Ascgen 2

3.把每张字符画读出来,显示在控制台中;

是不是很简单!?别吐槽我(前两步都用软件,根本没技术含量嘛)。

所以关键在第三步的代码,就是用了文件流读取输出。。。

1.读取字符画函数;

int FileRead(char *path){FILE *pfile=fopen(path,"rb");if (pfile==NULL){printf("open error!");return 0;}/*int ch;do{ch=fgetc(pfile);putch(ch);}while (ch!=EOF);*/char buffer[128]={};char *error;do{error=fgets(buffer,sizeof(buffer),pfile);printf("%s",buffer);strcpy(buffer,"");}while (error!=NULL);fclose(pfile);return 0;}
上文中的:
int ch;do{ch=fgetc(pfile);putch(ch);}while (ch!=EOF);

是逐个逐个字符地读取,后来发现效率有点低,就换成了整行读取:

char buffer[128]={};char *error;do{error=fgets(buffer,sizeof(buffer),pfile);printf("%s",buffer);strcpy(buffer,"");}while (error!=NULL);


2.数字转换成特定字符串

//一般帧数由0001-????,要把当前要读取文本序号转换成特定字符串//根据我用的字符画转换器的尿性,我需要把数字1转换为字符串0001,10转成0010等char* converto(int num){char temp[5]={};char result[5]="0";itoa(num,temp,10);if (num<10){strcat(result,"00");//strcat就是把参数二粘贴到参数一末尾,并覆盖\0,在末尾新建\0strcat(result,temp);}else if(num<100&&num>9){strcat(result,"0");strcat(result,temp);}else if(num<1000){strcat(result,temp);}else{strcpy(result,temp);}return result;}

3.清屏

系统自带的dos清屏函数system("cls")效率太低,导致播放卡顿,于是我百度(google)一下,直接找了一个新的清屏函数(别打我)
#include <windows.h>#define PERR(bSuccess, api){if(!(bSuccess)) printf("%s:Error %d from %s on line %d\n", __FILE__,GetLastError(), api, __LINE__);}void MyCls(HANDLE) ;int FileRead(char *path);char* converto(int num);inline void clrscr(void){HANDLE hStdOut=GetStdHandle(STD_OUTPUT_HANDLE);MyCls(hStdOut);return;}

void MyCls(HANDLE hConsole){COORD coordScreen={0,0};//设置清屏后光标返回的屏幕左上角坐标BOOL bSuccess;DWORD cCharsWritten;CONSOLE_SCREEN_BUFFER_INFO csbi;//保存缓冲区信息DWORD dwConSize;//当前缓冲区可容纳的字符数bSuccess=GetConsoleScreenBufferInfo(hConsole,&csbi);//获得缓冲区信息PERR(bSuccess,"GetConsoleScreenBufferInfo");dwConSize=csbi.dwSize.X * csbi.dwSize.Y;//缓冲区容纳字符数目//用空格填充缓冲区bSuccess=FillConsoleOutputCharacter(hConsole,(TCHAR)' ',dwConSize,coordScreen,&cCharsWritten);PERR(bSuccess,"FillConsoleOutputCharacter");bSuccess=GetConsoleScreenBufferInfo(hConsole,&csbi);//获得缓冲区信息PERR(bSuccess,"ConsoleScreenBufferInfo");//填充缓冲区属性bSuccess=FillConsoleOutputAttribute(hConsole,csbi.wAttributes,dwConSize,coordScreen,&cCharsWritten);PERR(bSuccess,"FillConsoleOutputAttribute");//光标返回屏幕左上角坐标bSuccess=SetConsoleCursorPosition(hConsole,coordScreen);PERR(bSuccess,"SetConsoleCursorPosition");return;}


效率明显比system("cls")高多了~~

4.main

把以上组装~
#include <stdio.h>#include <conio.h>#include <stdlib.h>#include <string>//.............int main(){char path[96];int num=1;//帧数char *txtnum=new char[5];while (num<=6572){txtnum=converto(num);//转换strcat(path,"F:\\output\\txt\\ASCII-【東方】Bad+Apple!! PV【影絵】sm8628149 ");strcat(path,txtnum);strcat(path,".txt");//以上为拼装文件路径path//printf(path);FileRead(path);printf("\n\nPage:%d",num);num++;strcpy(path,"");//system("cls");Sleep(20);//控制每帧之间间隔clrscr();}printf("%s","thanks for watching~\n");delete[] txtnum;return 0;}


5.效果

长宽比不对,导致效果不是很好呢~

像bad apple这样的影绘还好,如果视频的颜色画面丰富起来,就呵呵。。。



0 0
原创粉丝点击