最近刚写完c++的大作业,觉得挺有意思,所以就拿来和大家分享交流一下

下面是要求

一.基本要求

使用C++语言编写程序,在控制台(字符界面)上实现图片浏览。

基本功能包括:

1. 能够浏览同一个文件夹下所有的图片,而不是只能用输入名字的方式浏览。

2. 实现图片的彩色显示。

3. 界面友好,操作简便。

4. 编写一个文档,包括程序的基本模块说明,核心功能的实现方法,人员分工等。

不要求可以显示所有的图片,只需能够浏览24位色,不超过150*150的小图片。符合要求的图片可以使用photoshop或者画图板自行制作(可以用示例中自带的图片进行测试)。

这是成品

代码如下

#include "stdafx.h"
#include <stdlib.h>
#include <iostream>
#include <Windows.h>
#include<conio.h>
#include <stdio.h>
#include <io.h>
#include <time.h>
using namespace std;
/*
求近似颜色
按照老师给的图片,这些都是24位的bmp图片,所以从其位图数据可以得到每个像素的RGB值分量,R为red,G为green,B为blue
通过RGB可以显示的颜色是很多种的,而控制台只有16种背景颜色,下面列出了14种
所以我们要将每个像素的颜色近似成这14种颜色
你可以将R,G,B想象成X,Y,Z,建立一个空间坐标系,所以,哪两个点的距离最近那么颜色也就最接近
*/
WORD RED = BACKGROUND_RED | BACKGROUND_INTENSITY;//red: 255 green: 0  blue: 0
WORD RED_DARK = BACKGROUND_RED ;//128,0,0
WORD BLUE = BACKGROUND_BLUE | BACKGROUND_INTENSITY;//0 0 255
WORD BLUE_DARK = BACKGROUND_BLUE ;//0,0,128
WORD GREEN = BACKGROUND_GREEN | BACKGROUND_INTENSITY;//0 255 0
WORD GREEN_DARK = BACKGROUND_GREEN ;//0,128,0
WORD MAGENTA = BACKGROUND_BLUE | BACKGROUND_RED | BACKGROUND_INTENSITY;//255 0 255
WORD MAGENTA_DARK = BACKGROUND_BLUE | BACKGROUND_RED ;//128,0,128
WORD CYAN = BACKGROUND_GREEN |BACKGROUND_BLUE |BACKGROUND_INTENSITY;//0 255 255
WORD CYAN_DARK = BACKGROUND_GREEN | BACKGROUND_BLUE ;//0,128,128
WORD YELLOW = BACKGROUND_RED |BACKGROUND_GREEN |BACKGROUND_INTENSITY;//255 255 0
WORD YELLOW_DARK = BACKGROUND_RED | BACKGROUND_GREEN ;//128,128,0
WORD BLACK = 0;//0,0 0
WORD WHITE = BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE | BACKGROUND_INTENSITY;//255 255 255
/*
建立一个Color类,里面有四个属性
int R;  RGB中的红色分量
int G;  RGB中的绿色分量
int B;  RGB中的蓝色分量
WORD value; SetConsoleTextAttribute()中第二个参数的类型,也就是字体背景颜色
还有一个以这四个为参数的构造函数
*/
class Color {
public:WORD Value;int R,G,B;Color() {}Color(WORD value, int r, int g, int b) {Value = value;R = r;G = g;B = b;}
};
/*
对tm时间进行处理,得到类似如下的时间格式
2017年12月8日  星期五  22:43:19   .
getTime函数
year    从1900开始计时,所以加上1900
month   0是一月,所以加一
day     几月几号的号,不用处理
weekDay 一个星期的第几天,0是周日,以此类推.为此专门建立一个getwDay函数,传入数字,通过switch判断,返回汉字日 一 二等
hour minute second 小时分钟秒,不用处理
最后建立字符数组date,返回我们需要的时间格式
*/
class TimeUtils {
public:static char* getTime(tm time) {long year = time.tm_year + 1900;long month = time.tm_mon + 1;long day = time.tm_mday;char weekDay[10];strcpy(weekDay, getwDay((int)time.tm_wday));long hour = time.tm_hour;long minute = time.tm_min;long second = time.tm_sec;char date[100];sprintf(date, "%ld年%ld月%ld日  星期%s  %ld:%ld:%ld     ", year, month, day, weekDay, hour, minute, second);return date;}static char* getwDay(int d) {switch (d){case 0:return "日";break;case 1:return "一";break;case 2:return "二";break;case 3:return "三";break;case 4:return "四";break;case 5:return "五";break;case 6:return "六";break;default:break;}}
};
/*
建立一个Color类数组,将上面十四种颜色变成Color类都储存进去
*/
Color colors[14] = { Color(RED,255,0,0),Color(RED_DARK,128,0,0),Color(BLUE,0,0,255),Color(BLUE_DARK,0,0,128),Color(GREEN,0,255,0),
Color(GREEN_DARK,0,128,0),Color(MAGENTA,255,0,255),Color(MAGENTA_DARK,128,0,128),Color(CYAN,0,255,255),Color(CYAN_DARK,0,128,128),
Color(YELLOW,255,255,0),Color(YELLOW_DARK,128,128,0),Color(BLACK,0,0,0),Color(WHITE,255,255,255) };
/*
这个方法就是得到一个颜色的近似色
参数为一个像素的RGB值的三个分量
原理:
value代表这个像素点与数组里某个颜色的"距离"(RGB类比XYZ),将value一开始设置的尽量大点
tmp是临时储存一个"距离"
index代表colors数组的第几个颜色
pow(x,y)代表x的y次方
进行一个for循环,将传入的颜色与每个颜色对比
最后返回距离最近的颜色
*/
Color getColor(int r,int g,int b) {
int value = 1000000;
int tmp = 0;
int index = 10;
for (int i = 0; i <14; i++)
{tmp = pow((colors[i].R - r), 2)+ pow((colors[i].G - g), 2) + pow((colors[i].B - b), 2) ;if (tmp<=value){value = tmp;index = i;}
}
return colors[index];
}
/*
该函数可以在控制台画出一个bmp格式文件,参数为当前文件夹图片名首先要搞清楚24位bmp图的结构
由三部分组成
1.文件头
文件头里面的信息是我们不需要的
2.信息头
这里面有图片的格式,宽度,高度等信息
3.位图数据
图片的像素详细信息;这里面的每个值都是0-255的数字,代表某个R,G或B的值
比如,开头三个连在一起是一个像素点的RGB值,然后接着三个又是下一个像素点,以此类推
*/
void drawImage(const char* fileName) {unsigned char *pBmpBuf;//读入图像数据的指针int bmpWidth;//图像的宽int bmpHeight;//图像的高int biBitCount;//图像类型,每像素位数BITMAPINFOHEADER head;//信息头FILE *fp = fopen(fileName, "rb");//fp为文件指针,fopen()为打开一个文件的函数,第一个参数为文件名,第二个为读取方式,r代表read读取,b代表byte字节fseek(fp, sizeof(BITMAPFILEHEADER), 0);//fseek()表示在一个文件内寻找;参数依次为 文件指针  跳过的长度  开始位置fread(&head, sizeof(BITMAPINFOHEADER), 1, fp);//freed表示 从文件fp里,读取1个长度为sizeof(BITMAPINFOHEADER)数据,储存到地址&head里bmpWidth = head.biWidth;bmpHeight = head.biHeight;biBitCount = head.biBitCount;int lineByte = bmpWidth * biBitCount / 8;//每一行的字节数,因为像素RGB值分量有三个,所以这是应该是宽度*3,由于是24位图,所以/8;pBmpBuf = new unsigned  char[lineByte * bmpHeight];//定义指针指向的数据大小fread(pBmpBuf, 1, lineByte * bmpHeight, fp);//读取数据,将图片位图数据储存到已经开辟好的临时缓存区int i = bmpHeight*bmpWidth - bmpWidth;//i代表指针位置,由于位图数据的存储是倒过来的,所以第一行第一个应该是最后一行第一个int count = 1;//代表指针位于当前行的位置while (true){//设置字体背景颜色SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), getColor(pBmpBuf[3 * i + 2], pBmpBuf[3 * i + 1], pBmpBuf[3 * i]).Value);//打印空格printf(" ");//当前行位置右移count++;//指针位置右移i++;//如果读到当前最后一行if (count == bmpWidth){//指针进入上一行的第一个i = i - 2 * bmpWidth + 1;//位于当前行第一个count = 1;//图片打印换行printf("\n");}//如果读完,循环结束if (i<0){break;}}//将字体背景色设置回黑色SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),BLACK);fclose(fp);//关闭文件
}
/*
该函数会遍历当前文件夹内所有bmp格式图片,并将图片的相关信息写入一个文本文档中
参数为文本文档名,如果没有该文件则会新建,有则覆盖
*/
void writeMessage(const char* fileName) {//储存文件信息struct _finddata_t fileinfo;//可以将其理解为一个标识符,当你使用_findfirst时会返回一个值,如果为-1则表示找不到图片,//而后使用_findnext函数时需要传入该变量,继续上次的查找long hFile;//要打开或新建的文本文档FILE *file;//打开指定文件,第二个参数为打开方式,writefile = fopen(fileName, "w");//如果未找到bmp文件if ((hFile = _findfirst("*.bmp", &fileinfo)) == -1)return;else {do{//创建时间char createTime[100];//修改时间char writeTime[100];//赋值strcpy(createTime, TimeUtils::getTime(*localtime(&fileinfo.time_create)));strcpy(writeTime, TimeUtils::getTime(*localtime(&fileinfo.time_write)));//将信息写入文本文件fprintf(file, "文件名:%s\n创建时间:%s\n修改时间:%s\n", fileinfo.name, createTime, writeTime);fprintf(file, "文件大小:%dKB", fileinfo.size);fprintf(file, "\n\n");} while (_findnext(hFile, &fileinfo) == 0);}//关闭文件fclose(file);//结束遍历_findclose(hFile);
}
/*
先将图片信息都写入文本文件
而后开始遍历文件夹
在查找到一个图片后,先清屏,然后使用drawImage函数画出图片,使用getchar函数暂停程序
由于最外面是个参数为true的while循环,所以遍历文件夹结束后会重新开始遍历,
这样就会重新输出打印图片了
*/
int main() {writeMessage("图片信息.txt");struct _finddata_t fileinfo;long hFile;while (true){if ((hFile = _findfirst("*.bmp", &fileinfo)) == -1)return -1;else {do{system("cls");drawImage(fileinfo.name);getchar();} while (_findnext(hFile, &fileinfo) == 0);}_findclose(hFile);}return 0;}

c/c++控制台图片浏览相关推荐

  1. 原创“.NET研究”企业级控件库之图片浏览控件

    在上两篇:我介绍了原创企业级控件库之组合查询控件 和原创企业级控件库之大数据量分页控件,受到了很多朋友的支持,给了我很大的动力,在此我特表感谢.有的朋友要求把源码提供上来,我在第一篇就讲了,源码会在我 ...

  2. 图片浏览(CATransition)转场动画

    Main.storyboard ViewController.m // //  ViewController.m //  8A04.图片浏览(转场动画) // //  Created by huan ...

  3. iOS_“图片浏览选择”功能的编写思路

    最近重新开始练习iOS开发,找感觉. 先做个简单的图片浏览选择功能.不用管是难还是简单,先实现一下. 一.步骤概述 包含三个步骤: 创建页面:图片选择页(collectionView),图片预览页 处 ...

  4. 一起撸个朋友圈吧 图片浏览(上)【图片点击前景色】

    项目地址:github.com/razerdp/Fri- (能弱弱的求个star或者fork么QAQ) 上篇链接:一起撸个朋友圈吧 (Step6)- 评论对齐(点击评论对齐)[下] 下篇链接:一起撸个 ...

  5. vscode 预览图片 插件_真的动手写的VSCode的插件(图片浏览)之1

    由于本职工作中经常做图像处理,于时大量的图片浏览是不可避免的. 怎么样不离开最近经常使用的VSCode,同时去看大量的图像对我来讲就是个不错的需求,尤其是某个目录下的文件. 先谈基本的需求吧,显示一个 ...

  6. android ViewPager 图片浏览和保存图片

    在build.gradle在添加依赖 compile 'com.alibaba:fastjson:1.1.54.android' compile 'org.ligboy.retrofit2:conve ...

  7. android图片浏览功能,怎么在Android应用中实现一个网页图片浏览功能

    怎么在Android应用中实现一个网页图片浏览功能 发布时间:2020-12-05 17:28:31 来源:亿速云 阅读:80 作者:Leah 本篇文章给大家分享的是有关怎么在Android应用中实现 ...

  8. 表单-图片浏览上传-单选框(二)

    一.图片浏览上传 1.依然[table]标签包含, 2.[input]包含了[type]等于[file]. <table border="1" align="cen ...

  9. jquery插件图片浏览

    jquery插件图片浏览 jquery代码部分 (function($){$.fn.mPicsList = function(options){var picsImgs = $(this).find( ...

最新文章

  1. Android拖拽图片的实现
  2. bom头解释方法和去掉方法
  3. 安卓高手之路之 GDI图形引擎篇
  4. SqlServer 获取汉字的拼音首字母
  5. WIN2008 R2 Active Directory 之一 部署企业中第一台Windows Ser
  6. 洛谷 P4245 【模板】任意模数NTT
  7. jvm timezone
  8. thinkphp v5.0.11漏洞_ThinkPHP5丨远程代码执行漏洞动态分析
  9. php课程 10-35 php实现文件上传的注意事项是什么
  10. 2020 年,远程办公太难?技术大佬齐支招!
  11. 【爆牙齿】说说我期待中的苹果那块板子。
  12. scipy.special —— 排列、组合与阶乘
  13. vs中c语言图形显示,VS2010/MFC编程入门之四十九(图形图像:CDC类及其屏幕绘图函数)...
  14. 学计算机编程要学什么软件有哪些内容,加工中心自学电脑编程应该学习什么软件...
  15. Pluralistic Image Completion—多元图像补全—摘要翻译—测试教程(附源码)——CVPR 2019
  16. 火灾自动报警系统学习心得
  17. 老王家esp8266及老五家WS2818灯带
  18. ACL技术,NAT技术,园区网组网
  19. 我新开的淘宝店铺怎么增加访客和销量
  20. python glob.glob使用

热门文章

  1. 苹果cms10好看的模板
  2. 2022氯化工艺特种作业证考试题库及答案
  3. 加速火狐(firefox)浏览器
  4. 二维vector数组初始化方法
  5. 线性回归预测PM2.5
  6. 量子计算机 大数分解,关于大数分解问题的研究
  7. 视频文件头解析--wma
  8. 数据分析之淘宝数据简介
  9. DSP_F28335入门(1)——新建工程之gel文件解释
  10. 数字同步网时钟系统设计方案