标题: 控制台图形显示工具IMG.EXE [打印本页]
作者: happy886rr 时间: 2016-11-12 02:46 标题: 控制台图形显示工具IMG.EXE
本帖最后由 happy886rr 于 2016-11-13 00:34 编辑
强悍的控制台图形显示工具,支持jpg、png、bmp、gif(首帧)显示。内置脚本解析器,可以完成简单的goto跳转功能,用“::行号?循环次数”完成goto 跳转。使用gdiplus图形库;体积小巧、速度迅捷、功能实用、浅析脚本。
IMG.EXE
图片存为a.zip解压即是
-----------------------------------------------------------------------------
THE CONSOLE DISPLAYS PICTURE TOOL, VERSION 1.2, COPYRIGHT@2016~2018 BY HAPPY
img [options]
-----------------------------------------------------------------------------
: Hide the cursor
:::[time] Delay ms
::::: Show images in desktop
::[L]?[CYC] Cycle CYC times from row L
+{parameters} Cyclic accumulator
[imgfile] Direct display imgfile
[imgfile]:{parameters} Display the image with the given parameters
:{parameters} Erase the display with the given parameters
[scriptfile]::[m],[n] Get commands from [m] to [n] in the sfile
_____________________________________________________________________________
强悍的控制台图形显示工具,支持jpg、png、bmp、gif(首帧)显示。内置脚本解析器,
可以完成简单的goto跳转功能,用“::行号”完成goto 跳转。
_____________________________________________________________________________
隐藏光标
img :
延时500毫秒
:::500
在CMD窗口外显示图片
img :::::
省参数图形显示
img test.jpg
参数自动补全
img test.jpg:8,16
img test.jpg:8,16,100,200
img test.jpg:8,16,100,200,50,20
八参数图形显示
img test.jpg:cmd_x, cmd_y, size_W, size_H, src_x, src_y, disp_W, disp_H
擦除指定选区
img :start_cmd_x, end_cmd_x, start_cmd_y, end_cmd_y
从脚本中执行第3行到第8行
img test.txt::3,8
_____________________________________________________________________________
goto跳转语句 //::行号?循环次数
::12?80
循环累加器
+0,0,10,0
test.jpg:0,0,0,-1
::1?80
循环擦除
+0,0,10,0
test.jpg:0,0,0,-1
+0,10
:-10,0,0,800
::1?80
图片放大
:
:::::
+0,0,10,0
test.jpg:0,0,0,-1
::3?80
_____________________________________________________________________________
编译:- gcc img.c -std=gnu99 -O3 -s -lgdi32 -lgdiplus -oimg.exe
复制代码
源码:- /*
- THE CONSOLE DISPLAYS A PICTURE TOOL, VERSION 1.2
- IMG.EXE
- COPYRIGHT@2016~2018 BY HAPPY
- */
-
- //编译参数
- //gcc img.c -std=gnu99 -O3 -s -lgdi32 -lgdiplus -oimg.exe
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <stdbool.h>
- #include <windows.h>
- #include <gdiplus\gdiplus.h>
-
- //定义参数行
- char* ARGS[16];
-
- //定义计步器
- int PEDO[9]={0};
-
- //引入WINAPI
- HWND WINAPI GetConsoleWindow();
- HWND hCMD;
-
- //图形结构体
- typedef struct{
- HBITMAP hBitmap;
- int Width;
- int Height;
- }IMAGE;
-
- /***************图形函数群***************/
- //图形加载
- IMAGE LoadImg(char *file, int _nWidth, int _nHeight)
- {
- GpImage* thisImage;
- GpGraphics* graphics=NULL;
- ULONG_PTR gdiplusToken;
- IMAGE _img;
- GdiplusStartupInput GSI={1, NULL, false, false};
- HDC hdc=GetDC(NULL);
- HDC hdcMem=CreateCompatibleDC(hdc);
-
- int nLen=MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, file, -1, NULL, 0);
- if(nLen==0){
- exit(1);
- }
- wchar_t* wfile=(wchar_t*)malloc(sizeof(wchar_t)*nLen);
- MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, file, -1, wfile, nLen);
-
- GdiplusStartup(&gdiplusToken, &GSI, NULL);
- if( GdipLoadImageFromFile(wfile, &thisImage) ){
- fputs("Load image error.\n", stdout);
- exit(2);
- }
- GdipGetImageWidth(thisImage, &_img.Width);
- GdipGetImageHeight(thisImage, &_img.Height);
- if (_nHeight==-1 && _nWidth !=-1){
- _img.Height=(int)( (_img.Height*1.0 / _img.Width) * (_nWidth ) );
- _img.Width =_nWidth;
- }else if(_nWidth ==-1 && _nHeight!=-1){
- _img.Width =(int)( (_img.Width*1.0 / _img.Height) * (_nHeight) );
- _img.Height=_nHeight;
- }else if(_nHeight !=0 ){
- _img.Width =_nWidth;
- _img.Height=_nHeight;
- }
- _img.hBitmap=CreateCompatibleBitmap(hdc, _img.Width, _img.Height);
-
- SelectObject(hdcMem, _img.hBitmap);
- GdipCreateFromHDC(hdcMem, &graphics);
- GdipDrawImageRectI(graphics, thisImage, 0, 0, _img.Width, _img.Height);
- GdipDisposeImage(thisImage);
- GdipDeleteGraphics(graphics);
- DeleteDC (hdcMem);
- ReleaseDC(NULL, hdc);
- GdiplusShutdown(gdiplusToken);
- return _img;
- }
- //绘图函数
- int DrawImg(
- char* imgfile, //图形文件
- int cmd_x, int cmd_y, //相对于cmd窗口位置
- int size_W, int size_H, //图片的显示宽高
- int src_x, int src_y, //对相原图 截取位置
- int disp_W, int disp_H //要显示多少宽高
- ){
- cmd_x +=PEDO[0]*PEDO[1], cmd_y +=PEDO[0]*PEDO[2];
- size_W+=PEDO[0]*PEDO[3], size_H+=PEDO[0]*PEDO[4];
- src_x +=PEDO[0]*PEDO[5], src_y +=PEDO[0]*PEDO[6];
- disp_W+=PEDO[0]*PEDO[7], disp_H+=PEDO[0]*PEDO[8];
- PEDO[0]=0;
-
- IMAGE P =LoadImg(imgfile, size_W, size_H);
- HDC hCUR=GetDC(hCMD);
- HDC hSRC=CreateCompatibleDC(hCUR);
- SelectObject(hSRC, P.hBitmap);
- if(disp_W !=0){
- P.Width =disp_W, P.Height=disp_H;
- }
- BitBlt(hCUR, cmd_x, cmd_y, P.Width, P.Height, hSRC, src_x, src_y, SRCCOPY);
- DeleteObject(P.hBitmap);
- ReleaseDC(hCMD, hCUR);
- DeleteDC(hSRC);
- return 0;
- }
- //擦除画布
- int CleanImg(
- HWND hd, //句柄
- LONG left, //左坐标
- LONG right, //右坐标
- LONG top, //上坐标
- LONG bottom //底坐标
- ){
- RECT z={left+PEDO[0]*PEDO[1], top+PEDO[0]*PEDO[3], right+PEDO[0]*PEDO[2], bottom+PEDO[0]*PEDO[4]};
- InvalidateRect(hd, &z, true);
- return 0;
- }
-
- /***************功能函数群***************/
- //隐藏光标
- void HideCursor()
- {
- CONSOLE_CURSOR_INFO cursor_info={1,0};
- SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE),&cursor_info);
- }
- //查找字符
- int strchp(const char* Str, const char delim)
- {
- int i=-1;
- while(Str[++i]!='\0'){
- if(Str[i]==delim){
- return i;
- }
- }
- return -1;
- }
- //切分参数
- int args(char* Str, int FLAG)
- {
- int i=0;
- if(FLAG==1){
- ARGS[i]=strtok(Str, ":");
- }else{
- ARGS[i]=strtok(Str+1,",");
- }
- while(ARGS[i]!=NULL){ARGS[++i]=strtok(NULL,",");}
- return i;
- }
- //读取脚本
- int FileScript(char* txtfile, int m, int n);
- //参数分析
- int AnalysiTreatment(char* command)
- {
- int i=0, j=strchp(command, ':');
- switch(j){
- case -1:
- if(
- command[0]!='\0'&&
- command[0]!='\r'&&
- command[0]!='\t'&&
- command[0]!=' '
- ){
- DrawImg(command, 0, 0, 0, 0, 0, 0, 0, 0);
- }
- break;
- case 0:
- i=args(command, 0);
- if (i==4){
- CleanImg(hCMD, atol(ARGS[0]), atol(ARGS[1]), atol(ARGS[2]), atol(ARGS[3]));
- }else if(
- command[1]=='\0'||
- command[1]=='\r'||
- command[1]=='\t'||
- command[1]==' '
- ){
- HideCursor();
- }else{
- fputs("Error options.\n",stdout);
- }
- break;
- default:
- i=args(command, 1);
- if (command[j+1]==':' && i==3){
- FileScript(ARGS[0], atoi(ARGS[1]+1), atoi(ARGS[2]));
- }else if(command[j+1]==':' && i==2){
- FileScript(ARGS[0], atoi(ARGS[1]+1), atoi(ARGS[1]+1));
- }else if(i==3){
- DrawImg(ARGS[0], atoi(ARGS[1]), atoi(ARGS[2]), 0,0,0,0,0,0);
- }else if(i==5){
- DrawImg(ARGS[0], atoi(ARGS[1]), atoi(ARGS[2]), atoi(ARGS[3]), atoi(ARGS[4]), 0,0,0,0);
- }else if(i==7){
- DrawImg(ARGS[0], atoi(ARGS[1]), atoi(ARGS[2]), atoi(ARGS[3]), atoi(ARGS[4]), atoi(ARGS[5]), atoi(ARGS[6]), 0,0);
- }else if(i==9){
- DrawImg(ARGS[0], atoi(ARGS[1]), atoi(ARGS[2]), atoi(ARGS[3]), atoi(ARGS[4]), atoi(ARGS[5]), atoi(ARGS[6]), atoi(ARGS[7]), atoi(ARGS[8]));
- }else{
- fputs("Error options.\n",stdout);
- }
- break;
- }
- return 0;
- }
- //读取脚本
- int FileScript(char* txtfile, int m, int n)
- {
- FILE* fp;
- int i=0, j=0, k=0, c=0, MARK_PRE=0, MARK=0, MAX_ARGC=0;
- n=(n<0||n<m)?2147483618:n;
- if( (fp=fopen(txtfile, "rb"))==NULL ){
- fputs("Failed to read file.\n", stdout);
- exit(3);
- }
- char* Line=(char*)malloc(1024*sizeof(char));
- while(!feof(fp)){
- memset(Line, 0, 1024*sizeof(char));
- fgets(Line, 1023, fp);
- i++;
- if(
- Line[0]=='\0'||
- Line[0]=='\r'||
- Line[0]=='\t'||
- Line[0]==' '
- ){
- continue;
- }
- if(Line[0]=='+'){
- MAX_ARGC=args(Line, 0);
- for(j=0; j<MAX_ARGC; j++){
- PEDO[j+1]=atoi(ARGS[j]);
- }
- PEDO[0]=k;
- continue;
- }
- if(
- Line[0]==':'&&
- Line[1]==':'
-
- ){
- if(
- Line[2]!=':'&&
- i>=MARK_PRE
- ){
- k++;
- if(k==c){
- k=0;
- continue;
- }
- m=atoi(strtok(Line+2,"?"));
- c=atoi(strtok(NULL, "?"));
- MARK_PRE=i, i=0;
- fseek(fp, 0, SEEK_SET);
- }
- else if(
- Line[2]==':'&&
- i>=m
- ){
- if(Line[3]==':'&&Line[4]==':'){
- hCMD=GetDesktopWindow();
- }else{
- Sleep(atoi(Line+3));
- }
- }
- continue;
- }
- if(m<=i && i<=n){
- AnalysiTreatment(Line);
- }
- }
- free(Line);
- fclose(fp);
- return 0;
- }
-
- /*************MAIN主函数入口*************/
- int main(int argc, char** argv)
- {
- if(argc==2){
- hCMD=GetConsoleWindow();
- AnalysiTreatment(argv[1]);
- return 0;
- }
- fputs(
- "THE CONSOLE DISPLAYS A PICTURE TOOL, VERSION 1.2\n"
- "COPYRIGHT@2016~2018 BY HAPPY\n"
- "-------------------------------------------------------------------------\n"
- "img [options]\n"
- "-------------------------------------------------------------------------\n"
- " : Hide the cursor\n"
- " :::[time] Delay ms\n"
- " ::::: Show images in desktop\n"
- " ::[L]?[CYC] Cycle CYC times from row L\n"
- " +{parameters} Cyclic accumulator\n"
- " [imgfile] Direct display imgfile\n"
- " [imgfile]:{parameters} Display the image with the given parameters\n"
- " :{parameters} Erase the display with the given parameters\n"
- " [scriptfile]::[m],[n] Get commands from [m] to [n] in the sfile\n"
- "-------------------------------------------------------------------------\n"
- ,stdout
- );
- exit(1);
- }
复制代码
作者: codegay 时间: 2016-11-12 08:37
还真是做技术和开发的料子啊。
作者: 523066680 时间: 2016-11-12 08:58
本帖最后由 523066680 于 2016-11-12 09:05 编辑
嗖噶,有时候还是windows提供的接口比较省事。
比如之前用iconv就觉得有点繁琐,用 stringapiset.h 还直接
不过winapi 上面有一点我觉得很难接受,就是类型的命名感觉很别扭:
DWORD, LPCTSTR, LRESULT, HWND
作者: pcl_test 时间: 2016-11-12 09:11
应该是图片显示吧
作者: happy886rr 时间: 2016-11-13 00:50
回复 2# codegay
就是用来辅助批处理动画、游戏的,用这个可以放大缩小图片,后续还会添加图像旋转,gif解码,图形变换,伪3D等特效技术。之后还会写个3dimg.exe,用来在控制台窗口显示3d图形、3d建模,3d演示;由于是C语言构建,加上算法每天在不断的优化,性能貌似总比其他语言强太多。而img是一个浅析脚本,img有自己的脚本风格,且支持bat混编。- @echo off&img %~nx0::3,-1&exit /b
- >>>IMG图显脚本
- :
- +0,0,10,0
- test.jpg:0,0,0,-1
- +0,10
- :-10,0,0,800
- :::10
- >>>
- ::12?80
-
- +10,0,0,0
- test.jpg:0,0,0,0
- +0,10
- :-10,0,0,800
- :::10
- >>>
- ::10?80
复制代码
我只得出一个结论:在相同算法前提下,C语言比其他所有高级语言都快,python的大数运算很快,但我用C语言实现的大数运算速度是python的100倍,用C语言实现的其他项目也比C++写的快2到3倍。不过C语言开发效率很慢,你得清楚底层原理,有时还得用内联汇编,一天才写三四百行,慢的要死。
作者: happy886rr 时间: 2016-11-13 00:55
回复 3# 523066680
微软那些类型名称,我也看得眼花,正如windows系统,其实只是新瓶装旧酒,微软的一贯作风。
作者: happy886rr 时间: 2016-11-13 00:57
回复 4# pcl_test
是的,只是比bmp.exe功能多了几项,支持的图片格式多了几种,支持img自己的脚本。
作者: 523066680 时间: 2016-11-13 01:13
回复 7# happy886rr
版主的意思可能是,字面上,图形和图像包含的东西不一样。图像是像素化的,图形可能是矢量的。(逃
作者: CrLf 时间: 2016-11-13 01:48
骚年,我看好你哦
话说能丰富一下注释更好...(然而自己的都没加)捂脸...逃
作者: happy886rr 时间: 2016-11-13 10:13
感谢大师提醒,只是自己对语言掌握还不是很熟练,很多非常高深的数学变换,不知道该如何用程序语言去描述。这也是一个思维的转变,就是你必须学会机器的思维过程,写机器能理解的代码。机器喜欢做加法、位运算,所以你要尽量把代码里的乘法除法改成加法或位运算。同时,C语言的位运算速度令我惊呆了。
作者: 老刘1号 时间: 2016-11-18 22:34
回复 10# happy886rr
Xp x64光荣测试失败了
作者: happy886rr 时间: 2016-11-18 22:38
回复 11# 老刘1号
很正常,这个调用的是gdi32.dll 你的64位xp可能存在兼容性问题。
作者: 老刘1号 时间: 2016-11-18 22:49
回复 12# happy886rr
好吧……
作者: happy886rr 时间: 2016-11-18 23:00
回复 13# 老刘1号
对了,你再试一下image能否在64xp下工作。
作者: happy886rr 时间: 2016-11-18 23:01
你是不是用的64位的cmd
作者: 老刘1号 时间: 2016-11-19 09:21
回复 15# happy886rr
是啊
作者: 老刘1号 时间: 2016-11-19 09:31
回复 14# happy886rr
IMAGE.exe v1.7 xp x64下测试成功
作者: happy886rr 时间: 2016-11-19 09:41
本帖最后由 happy886rr 于 2016-11-19 09:44 编辑
回复 17# 老刘1号
你应该知道只显示bmp才能兼容,显示bmp不会调用gdiplus,但是你要显示其他多种格式jpg,gif,png那就得调用gdiplus,在64位cmd调用32位dll怎么可能,因此出错。你用32位cmd直接调用不就行了。
作者: 老刘1号 时间: 2016-11-19 10:16
回复 18# happy886rr
好,我再测试下
作者: 老刘1号 时间: 2016-11-19 10:20
回复 18# happy886rr
测试失败了
发觉了,我系统里没GDI+这个扩张……
作者: 老刘1号 时间: 2016-11-19 10:21
回复 18# happy886rr
建议集成一下
欢迎光临 批处理之家 (http://bbs.bathome.net/) |
Powered by Discuz! 7.2 |