1 00:00:00,000 --> 00:00:09,500 >> [音乐播放] 2 00:00:09,500 --> 00:00:12,350 >> ZAMYLA陈:这是思嘉小姐 与烛台。 3 00:00:12,350 --> 00:00:13,560 谁是凶手? 4 00:00:13,560 --> 00:00:15,030 好了,我们要找出答案。 5 00:00:15,030 --> 00:00:20,870 在棋盘游戏线索,你可能 给出一个物理红色图像。 6 00:00:20,870 --> 00:00:24,120 而且图像很红和 参差不齐,而你的工作是 7 00:00:24,120 --> 00:00:25,490 揭示了隐藏的消息。 8 00:00:25,490 --> 00:00:29,740 通常你用红色正在提供 放大镜,或红色屏幕 9 00:00:29,740 --> 00:00:31,410 揭示隐藏的消息。 10 00:00:31,410 --> 00:00:33,340 嗯,我们要去模仿。 11 00:00:33,340 --> 00:00:37,960 >> 在侦探小说,你给一个位图图像 这看起来非常参差不齐,红色, 12 00:00:37,960 --> 00:00:43,430 然后运行侦探小说程序 露出一个隐藏的信息。 13 00:00:43,430 --> 00:00:45,650 >> 因此,让我们打破这种分成几个步骤。 14 00:00:45,650 --> 00:00:50,390 首先,你要打开的文件 - 你已经被赋予了线索。 15 00:00:50,390 --> 00:00:53,880 然后还创建 判决书位图文件。 16 00:00:53,880 --> 00:00:58,240 然后,你要更新的位图 头对于判决结果输出文件信息。 17 00:00:58,240 --> 00:00:59,920 更多的后来。 18 00:00:59,920 --> 00:01:04,319 然后你要读入 线索,扫描,逐像素, 19 00:01:04,319 --> 00:01:07,320 改变像素颜色 必要时,和写作 20 00:01:07,320 --> 00:01:08,960 那些进入判决 - 21 00:01:08,960 --> 00:01:12,000 逐个像素进 判决书扫描线。 22 00:01:12,000 --> 00:01:13,780 >> 我们如何开始准备这件事? 23 00:01:13,780 --> 00:01:16,940 好了,幸运的是,我们有copy.c 在分配代码。 24 00:01:16,940 --> 00:01:21,240 并且这将证明 非常有用的给我们。 25 00:01:21,240 --> 00:01:29,700 Copy.c打开一个文件,读取该 INFILE的头,然后更新 26 00:01:29,700 --> 00:01:31,070 输出文件的标头。 27 00:01:31,070 --> 00:01:37,010 然后将其读出的每个像素中的 扫描线,逐个象素,然后 28 00:01:37,010 --> 00:01:42,390 写道像素到输出文件。 29 00:01:42,390 --> 00:01:45,020 >> 所以,你的第一个步骤可能 可以运行下面的 30 00:01:45,020 --> 00:01:46,420 命令,在终端 - 31 00:01:46,420 --> 00:01:50,270 CP copy.c whodunit.c。 32 00:01:50,270 --> 00:01:55,320 这将创建的副本 copy.c命名whodunit.c。 33 00:01:55,320 --> 00:01:58,320 所以我们的第一步打开 文件,好了,有一个确切的 34 00:01:58,320 --> 00:02:00,070 的,在copy.c.副本 35 00:02:00,070 --> 00:02:03,360 所以,我将离开你看看那个。 36 00:02:03,360 --> 00:02:07,860 >> 我们现在在这个PSET处理的 文件I / O,基本回吐文件, 37 00:02:07,860 --> 00:02:10,229 阅读,写作,编辑它们。 38 00:02:10,229 --> 00:02:12,650 你怎么先打开一个文件? 39 00:02:12,650 --> 00:02:16,800 好吧,你要申报文件 指针,然后调用 40 00:02:16,800 --> 00:02:18,670 功能打开。 41 00:02:18,670 --> 00:02:23,150 通过在路径中,或者该名称 文件,然后您需要的模式 42 00:02:23,150 --> 00:02:24,700 英寸打开该文件 43 00:02:24,700 --> 00:02:28,620 通过在R将打开 foo.bmp阅读。 44 00:02:28,620 --> 00:02:35,670 而FOPEN与传递一个W将 开放bar.bmp,写文件和 45 00:02:35,670 --> 00:02:37,020 其实编辑它。 46 00:02:37,020 --> 00:02:41,970 >> 所以,现在,我们已经打开的文件,我们 下一步是更新的头信息 47 00:02:41,970 --> 00:02:43,230 为输出文件。 48 00:02:43,230 --> 00:02:44,610 什么是头信息? 49 00:02:44,610 --> 00:02:48,160 嗯,首先我们需要知道 什么是位图。 50 00:02:48,160 --> 00:02:51,000 位图只是一个简单的 字节排列。 51 00:02:51,000 --> 00:02:55,480 他们在这个文件正在申报 在这里,在bmp.h,带着一帮 52 00:02:55,480 --> 00:02:58,610 一个什么样的位图信息 实际上是做出来的。 53 00:02:58,610 --> 00:03:05,730 但是,我们真正关心的是什么 位图文件头,就在这里,和 54 00:03:05,730 --> 00:03:08,460 位图信息头,在这里。 55 00:03:08,460 --> 00:03:13,170 头是由一对夫妇 变量将证明是非常有用的。 56 00:03:13,170 --> 00:03:18,400 有成员biSizeImage,这是 以字节为单位的图像的总大小。 57 00:03:18,400 --> 00:03:20,890 这包括像素和填充。 58 00:03:20,890 --> 00:03:24,210 填充是非常重要的,但 我们将在稍后。 59 00:03:24,210 --> 00:03:30,000 >> BiWidth代表的宽度 图像中的像素减去填充。 60 00:03:30,000 --> 00:03:34,220 BiHeight然后还高度 以像素为单位的图像。 61 00:03:34,220 --> 00:03:38,240 然后BITMAPFILEHEADER和 BITMAPINFOHEADER,正如我所说 62 00:03:38,240 --> 00:03:40,900 早些时候,这些都代表 作为结构。 63 00:03:40,900 --> 00:03:45,410 所以,你不能访问该文件头 本身,而是你要得到 64 00:03:45,410 --> 00:03:47,370 这些变量里面。 65 00:03:47,370 --> 00:03:48,170 >> 确定。 66 00:03:48,170 --> 00:03:50,600 那么,我们如何更新的头信息? 67 00:03:50,600 --> 00:03:54,020 嗯,首先我们要看看我们是否 需要从改变任何信息 68 00:03:54,020 --> 00:03:58,480 infile中的线索,到 OUTFILE,判决。 69 00:03:58,480 --> 00:04:00,250 是什么改变这种情况? 70 00:04:00,250 --> 00:04:04,320 好吧,其实不是,因为我们要去 要只是改变了颜色。 71 00:04:04,320 --> 00:04:07,550 我们不会被改变文件 的大小,图像的大小,宽度, 72 00:04:07,550 --> 00:04:08,310 或高度。 73 00:04:08,310 --> 00:04:14,010 所以你所有的权利现在 只是复制每个像素。 74 00:04:14,010 --> 00:04:14,840 >> 确定。 75 00:04:14,840 --> 00:04:20,720 所以,现在让我们来看看如何实际我们 可以从文件中读取每一个像素。 76 00:04:20,720 --> 00:04:23,640 另一个文件I / O功能 将开始发挥作用 - 77 00:04:23,640 --> 00:04:24,700 FREAD。 78 00:04:24,700 --> 00:04:28,440 这需要在一个指向该结构 将包含字节 79 00:04:28,440 --> 00:04:30,110 你正在阅读。 80 00:04:30,110 --> 00:04:31,890 所以,你正在阅读到这一点。 81 00:04:31,890 --> 00:04:36,090 然后你传递一个大小,这是 每个元素的大小,你 82 00:04:36,090 --> 00:04:37,360 想读。 83 00:04:37,360 --> 00:04:40,640 这里,函数sizeof 会派上用场。 84 00:04:40,640 --> 00:04:45,570 然后,你将在数量上,这 表示的元素的数目 85 00:04:45,570 --> 00:04:47,480 大小来读取。 86 00:04:47,480 --> 00:04:51,180 然后最后,inptr,这是 你是将文件指针 87 00:04:51,180 --> 00:04:52,530 从去阅读。 88 00:04:52,530 --> 00:04:58,650 因此,所有这些元素都在里面 inptr和他们要的数据。 89 00:04:58,650 --> 00:05:01,660 >> 让我们看一个小例子。 90 00:05:01,660 --> 00:05:07,590 如果我想读入数据两只狗, 好了,我可以做到这一点的两种方法之一。 91 00:05:07,590 --> 00:05:15,250 我可以读大小的两个对象 从我inptr的狗,或者我可以读 92 00:05:15,250 --> 00:05:19,280 在一个对象的两个狗的大小。 93 00:05:19,280 --> 00:05:23,580 所以你看到,这取决于方式 你安排的大小和数量,您 94 00:05:23,580 --> 00:05:25,840 可以在相同的字节数读出。 95 00:05:25,840 --> 00:05:28,720 96 00:05:28,720 --> 00:05:33,020 >> 所以,现在,让我们来改变 因为我们需要的像素颜色。 97 00:05:33,020 --> 00:05:37,320 如果你看看在bmp.h一遍,然后 你会看到在底部 98 00:05:37,320 --> 00:05:42,920 RGBTRIPLEs是另一种结构,其中 它们是由三个字节。 99 00:05:42,920 --> 00:05:49,220 一,rgbtBlue,rgbtGreen和rgbtRed。 100 00:05:49,220 --> 00:05:52,480 所以每一个都代表了额 蓝色,绿色的数量,并且 101 00:05:52,480 --> 00:05:57,250 该像素内金额红色的,其中 每个量是由一个表示 102 00:05:57,250 --> 00:05:58,670 十六进制数。 103 00:05:58,670 --> 00:06:04,370 >> 所以FF0000将是一个蓝色的颜色, 因为它从蓝色, 104 00:06:04,370 --> 00:06:05,850 绿色,红色。 105 00:06:05,850 --> 00:06:09,300 然后全F的地址将是白色的。 106 00:06:09,300 --> 00:06:13,440 让我们来看看smiley.bmp,这 你有你的分销代码。 107 00:06:13,440 --> 00:06:15,690 如果您在短短的一个图像打开它 浏览器,那么你会 108 00:06:15,690 --> 00:06:17,080 刚看到一个红色的笑脸。 109 00:06:17,080 --> 00:06:20,380 但考虑更深的下潜中,​​我们将 见,该结构 110 00:06:20,380 --> 00:06:22,340 它仅仅是像素。 111 00:06:22,340 --> 00:06:25,880 我们有白色像素, 然后红色像素。 112 00:06:25,880 --> 00:06:31,000 白色,FFFFFF,然后将所有的 红色像素,我在上色为你 113 00:06:31,000 --> 00:06:35,440 在这里,你可以看到他们是0000FF。 114 00:06:35,440 --> 00:06:39,760 蓝零,零绿,全红。 115 00:06:39,760 --> 00:06:45,350 而且,由于笑脸是8个像素宽, 我们没有任何填充。 116 00:06:45,350 --> 00:06:47,360 好的。 117 00:06:47,360 --> 00:06:53,310 >> 所以,如果我是分配不同的值 到RGBTRIPLE,我想 118 00:06:53,310 --> 00:06:58,350 使其绿色,那么我会做的是 我想声明一个RGBTRIPLE,命名 119 00:06:58,350 --> 00:07:02,660 三,然后进入每 该结构我内字节 120 00:07:02,660 --> 00:07:04,030 会使用点运算符。 121 00:07:04,030 --> 00:07:08,430 所以triple.rgbtBlue,我可以 指派为0。 122 00:07:08,430 --> 00:07:13,460 绿色的,我可以把它分配给全 - 任何 号,说真的,介于0和FF。 123 00:07:13,460 --> 00:07:15,470 再红,我也想说0。 124 00:07:15,470 --> 00:07:19,160 这样的话,让我一个绿色像素。 125 00:07:19,160 --> 00:07:23,030 >> 接下来,如果我要检查什么 东西的价值? 126 00:07:23,030 --> 00:07:27,250 我可以有一些检查 三重的rgbtBlue值是否为 127 00:07:27,250 --> 00:07:31,080 FF和再打印,“我感觉 蓝色的!“,作为一个结果。 128 00:07:31,080 --> 00:07:35,640 现在,这并不一定意味着 该像素是蓝色的,对不对? 129 00:07:35,640 --> 00:07:40,060 因为像素的绿色和红色值 也可具有非0值。 130 00:07:40,060 --> 00:07:43,470 所有这意味着,以及所有 这是检查是 131 00:07:43,470 --> 00:07:45,610 一个完整的蓝色。 132 00:07:45,610 --> 00:07:50,050 但是,所有的像素可能也有部分 颜色值,这样 133 00:07:50,050 --> 00:07:52,180 这里在下一个例子。 134 00:07:52,180 --> 00:07:55,400 >> 这是一个有点难以看 这个形象是什么了。 135 00:07:55,400 --> 00:08:00,320 这看起来更有点像 clue.bmp,你会得到。 136 00:08:00,320 --> 00:08:03,600 现在,身体上,你可能会解决这个问题, 因为有大量的红,由 137 00:08:03,600 --> 00:08:07,040 拿着一个红色的屏幕图像,这样 那其他颜色可以出现。 138 00:08:07,040 --> 00:08:10,968 那么,我们如何模仿这种用c? 139 00:08:10,968 --> 00:08:15,640 好了,我们可能会删除所有红色 从整个影像。 140 00:08:15,640 --> 00:08:21,870 所以要做到这一点,我们会设置每 象素的红色值设置为0。 141 00:08:21,870 --> 00:08:25,020 这样一来,图像会显得有点 像这样,在那里我们有没有红色的位 142 00:08:25,020 --> 00:08:26,300 无论什么。 143 00:08:26,300 --> 00:08:29,390 >> 我们可以看到隐藏的讯息 更清楚现在点点。 144 00:08:29,390 --> 00:08:31,730 它的另一个笑脸。 145 00:08:31,730 --> 00:08:33,870 或者,也许我们可以用另一种方法。 146 00:08:33,870 --> 00:08:36,480 也许,我们可以识别 所有的红色像素 - 147 00:08:36,480 --> 00:08:41,100 也就是说,所有的像素与 0蓝色,绿色0和0红 - 148 00:08:41,100 --> 00:08:43,169 并改变那些白色。 149 00:08:43,169 --> 00:08:45,470 而我们的图像看起来可能 这样的事情。 150 00:08:45,470 --> 00:08:48,250 有一点比较容易看到。 151 00:08:48,250 --> 00:08:51,170 >> 有很多其他的方法来发现 秘密消息为好, 152 00:08:51,170 --> 00:08:53,730 处理的颜色处理。 153 00:08:53,730 --> 00:08:57,050 也许你可能会使用的方法之一 我上面提到的。 154 00:08:57,050 --> 00:08:59,600 ,另外,您可能希望 提升一些颜色 155 00:08:59,600 --> 00:09:02,620 并把那些出。 156 00:09:02,620 --> 00:09:06,190 >> 所以,现在我们已经改变了像素 色彩,接下来我们只需要编写他们 157 00:09:06,190 --> 00:09:08,500 在到该扫描线,逐个像素。 158 00:09:08,500 --> 00:09:11,860 并再次,你要回头 到copy.c,如果你还没有被复制 159 00:09:11,860 --> 00:09:18,170 它已经,并期待在fwrite的 函数,它接受数据,一个指针 160 00:09:18,170 --> 00:09:23,230 到包含该字节的结构 你是从,大小阅读 161 00:09:23,230 --> 00:09:26,610 的项目,项目的数目, 然后outptr - 162 00:09:26,610 --> 00:09:29,450 这些文件的目的。 163 00:09:29,450 --> 00:09:34,010 >> 当您在像素写,你会 还必须在填充写。 164 00:09:34,010 --> 00:09:34,970 什么是填充? 165 00:09:34,970 --> 00:09:38,670 那么,每一个像素RGBT 是3字节长。 166 00:09:38,670 --> 00:09:43,670 但是,扫描线为位图图像 必须的4个字节的倍数。 167 00:09:43,670 --> 00:09:47,650 如果象素的数目不是 多四个,那么我们就需要添加 168 00:09:47,650 --> 00:09:48,880 这种填充。 169 00:09:48,880 --> 00:09:51,420 填充,只需0表示。 170 00:09:51,420 --> 00:09:54,380 那么,我们该如何写,或读这个? 171 00:09:54,380 --> 00:09:59,280 嗯,事实证明,你不能 其实用fread填充,但你可以 172 00:09:59,280 --> 00:10:00,970 计算。 173 00:10:00,970 --> 00:10:04,400 >> 在这种情况下,线索和判决 具有相同的宽度,所以 174 00:10:04,400 --> 00:10:05,910 填充是相同的。 175 00:10:05,910 --> 00:10:09,370 和填充,因为你会看到 在copy.c,计算 176 00:10:09,370 --> 00:10:11,790 用下面的公式 - 177 00:10:11,790 --> 00:10:16,690 bi.biWidth倍的sizeof(RGBTRIPLE)会 给我们多少字节的bmp 178 00:10:16,690 --> 00:10:18,280 有每一行中。 179 00:10:18,280 --> 00:10:21,890 从那里,模数和减法 与4可以计算出 180 00:10:21,890 --> 00:10:25,610 许多字节必须被添加,使得 在字节倍数 181 00:10:25,610 --> 00:10:27,250 每一行是4。 182 00:10:27,250 --> 00:10:30,490 >> 现在,我们有公式 我们多么需要填充,现在 183 00:10:30,490 --> 00:10:31,610 我们可以写它。 184 00:10:31,610 --> 00:10:34,080 现在,我之前提到的, 填充仅仅是0。 185 00:10:34,080 --> 00:10:39,730 因此,在这种情况下,我们只是把 一个字符,在这种情况下为0,进入我们 186 00:10:39,730 --> 00:10:41,710 outptr - 我们的输出文件。 187 00:10:41,710 --> 00:10:47,530 所以这只能说是的fputc 0,逗号outptr。 188 00:10:47,530 --> 00:10:52,400 >> 所以,虽然我们一直在阅读到我们的 文件,文件I / O一直跟踪我们 189 00:10:52,400 --> 00:10:57,440 在与一些这些文件的位置 调用的文件位置指示器。 190 00:10:57,440 --> 00:10:59,350 把它看成是一个光标。 191 00:10:59,350 --> 00:11:03,550 基本上,它前进的每一次 我们FREAD,但我们有 192 00:11:03,550 --> 00:11:05,671 控制了这一点。 193 00:11:05,671 --> 00:11:11,030 >> 如果要移动的文件位置指示器, 您可以使用函数fseek的。 194 00:11:11,030 --> 00:11:15,600 其中inptr表示文件 您正在寻找的指针, 195 00:11:15,600 --> 00:11:20,370 量的字节数,你 要移动光标,然后从 196 00:11:20,370 --> 00:11:23,470 涉及的基准点 从光标所在处。 197 00:11:23,470 --> 00:11:26,770 如果传入SEEK_CUR,那 表示当前 198 00:11:26,770 --> 00:11:28,100 在文件中的位置。 199 00:11:28,100 --> 00:11:31,020 或者您可以使用其他一些参数。 200 00:11:31,020 --> 00:11:35,400 所以,我们可能要使用FSEEK跳过 在文件中的填充。 201 00:11:35,400 --> 00:11:39,410 再次,如果你坚持,有 的,在copy.c.一个例子 202 00:11:39,410 --> 00:11:43,260 >> 所以,现在我们已经打开的文件, 的线索,并判决。 203 00:11:43,260 --> 00:11:46,450 我们已经更新了头信息 我们的判决,因为每 204 00:11:46,450 --> 00:11:48,730 位图需要的标头。 205 00:11:48,730 --> 00:11:52,280 我们然后读入线索的 扫描线,逐个像素,改变 206 00:11:52,280 --> 00:11:55,210 每一个颜色的需要,并 写那些进入 207 00:11:55,210 --> 00:11:57,340 判决,逐像素。 208 00:11:57,340 --> 00:12:01,550 一旦你打开的判决,你可以看到谁 罪魁祸首,还是什么秘密 209 00:12:01,550 --> 00:12:02,850 消息。 210 00:12:02,850 --> 00:12:05,550 我的名字是Zamyla,并 这是侦探小说。 211 00:12:05,550 --> 00:12:12,864