[音乐播放] ZAMYLA陈:这是思嘉小姐 与烛台。 谁是凶手? 好了,我们要找出答案。 在棋盘游戏线索,你可能 给出一个物理红色图像。 而且图像很红和 参差不齐,而你的工作是 揭示了隐藏的消息。 通常你用红色正在提供 放大镜,或红色屏幕 揭示隐藏的消息。 嗯,我们要去模仿。 在侦探小说,你给一个位图图像 这看起来非常参差不齐,红色, 然后运行侦探小说程序 露出一个隐藏的信息。 因此,让我们打破这种分成几个步骤。 首先,你要打开的文件 - 你已经被赋予了线索。 然后还创建 判决书位图文件。 然后,你要更新的位图 头对于判决结果输出文件信息。 更多的后来。 然后你要读入 线索,扫描,逐像素, 改变像素颜色 必要时,和写作 那些进入判决 - 逐个像素进 判决书扫描线。 我们如何开始准备这件事? 好了,幸运的是,我们有copy.c 在分配代码。 并且这将证明 非常有用的给我们。 Copy.c打开一个文件,读取该 INFILE的头,然后更新 输出文件的标头。 然后将其读出的每个像素中的 扫描线,逐个象素,然后 写道像素到输出文件。 所以,你的第一个步骤可能 可以运行下面的 命令,在终端 - CP copy.c whodunit.c。 这将创建的副本 copy.c命名whodunit.c。 所以我们的第一步打开 文件,好了,有一个确切的 的,在copy.c.副本 所以,我将离开你看看那个。 我们现在在这个PSET处理的 文件I / O,基本回吐文件, 阅读,写作,编辑它们。 你怎么先打开一个文件? 好吧,你要申报文件 指针,然后调用 功能打开。 通过在路径中,或者该名称 文件,然后您需要的模式 英寸打开该文件 通过在R将打开 foo.bmp阅读。 而FOPEN与传递一个W将 开放bar.bmp,写文件和 其实编辑它。 所以,现在,我们已经打开的文件,我们 下一步是更新的头信息 为输出文件。 什么是头信息? 嗯,首先我们需要知道 什么是位图。 位图只是一个简单的 字节排列。 他们在这个文件正在申报 在这里,在bmp.h,带着一帮 一个什么样的位图信息 实际上是做出来的。 但是,我们真正关心的是什么 位图文件头,就在这里,和 位图信息头,在这里。 头是由一对夫妇 变量将证明是非常有用的。 有成员biSizeImage,这是 以字节为单位的图像的总大小。 这包括像素和填充。 填充是非常重要的,但 我们将在稍后。 BiWidth代表的宽度 图像中的像素减去填充。 BiHeight然后还高度 以像素为单位的图像。 然后BITMAPFILEHEADER和 BITMAPINFOHEADER,正如我所说 早些时候,这些都代表 作为结构。 所以,你不能访问该文件头 本身,而是你要得到 这些变量里面。 确定。 那么,我们如何更新的头信息? 嗯,首先我们要看看我们是否 需要从改变任何信息 infile中的线索,到 OUTFILE,判决。 是什么改变这种情况? 好吧,其实不是,因为我们要去 要只是改变了颜色。 我们不会被改变文件 的大小,图像的大小,宽度, 或高度。 所以你所有的权利现在 只是复制每个像素。 确定。 所以,现在让我们来看看如何实际我们 可以从文件中读取每一个像素。 另一个文件I / O功能 将开始发挥作用 - FREAD。 这需要在一个指向该结构 将包含字节 你正在阅读。 所以,你正在阅读到这一点。 然后你传递一个大小,这是 每个元素的大小,你 想读。 这里,函数sizeof 会派上用场。 然后,你将在数量上,这 表示的元素的数目 大小来读取。 然后最后,inptr,这是 你是将文件指针 从去阅读。 因此,所有这些元素都在里面 inptr和他们要的数据。 让我们看一个小例子。 如果我想读入数据两只狗, 好了,我可以做到这一点的两种方法之一。 我可以读大小的两个对象 从我inptr的狗,或者我可以读 在一个对象的两个狗的大小。 所以你看到,这取决于方式 你安排的大小和数量,您 可以在相同的字节数读出。 所以,现在,让我们来改变 因为我们需要的像素颜色。 如果你看看在bmp.h一遍,然后 你会看到在底部 RGBTRIPLEs是另一种结构,其中 它们是由三个字节。 一,rgbtBlue,rgbtGreen和rgbtRed。 所以每一个都代表了额 蓝色,绿色的数量,并且 该像素内金额红色的,其中 每个量是由一个表示 十六进制数。 所以FF0000将是一个蓝色的颜色, 因为它从蓝色, 绿色,红色。 然后全F的地址将是白色的。 让我们来看看smiley.bmp,这 你有你的分销代码。 如果您在短短的一个图像打开它 浏览器,那么你会 刚看到一个红色的笑脸。 但考虑更深的下潜中,​​我们将 见,该结构 它仅仅是像素。 我们有白色像素, 然后红色像素。 白色,FFFFFF,然后将所有的 红色像素,我在上色为你 在这里,你可以看到他们是0000FF。 蓝零,零绿,全红。 而且,由于笑脸是8个像素宽, 我们没有任何填充。 好的。 所以,如果我是分配不同的值 到RGBTRIPLE,我想 使其绿色,那么我会做的是 我想声明一个RGBTRIPLE,命名 三,然后进入每 该结构我内字节 会使用点运算符。 所以triple.rgbtBlue,我可以 指派为0。 绿色的,我可以把它分配给全 - 任何 号,说真的,介于0和FF。 再红,我也想说0。 这样的话,让我一个绿色像素。 接下来,如果我要检查什么 东西的价值? 我可以有一些检查 三重的rgbtBlue值是否为 FF和再打印,“我感觉 蓝色的!“,作为一个结果。 现在,这并不一定意味着 该像素是蓝色的,对不对? 因为像素的绿色和红色值 也可具有非0值。 所有这意味着,以及所有 这是检查是 一个完整的蓝色。 但是,所有的像素可能也有部分 颜色值,这样 这里在下一个例子。 这是一个有点难以看 这个形象是什么了。 这看起来更有点像 clue.bmp,你会得到。 现在,身体上,你可能会解决这个问题, 因为有大量的红,由 拿着一个红色的屏幕图像,这样 那其他颜色可以出现。 那么,我们如何模仿这种用c? 好了,我们可能会删除所有红色 从整个影像。 所以要做到这一点,我们会设置每 象素的红色值设置为0。 这样一来,图像会显得有点 像这样,在那里我们有没有红色的位 无论什么。 我们可以看到隐藏的讯息 更清楚现在点点。 它的另一个笑脸。 或者,也许我们可以用另一种方法。 也许,我们可以识别 所有的红色像素 - 也就是说,所有的像素与 0蓝色,绿色0和0红 - 并改变那些白色。 而我们的图像看起来可能 这样的事情。 有一点比较容易看到。 有很多其他的方法来发现 秘密消息为好, 处理的颜色处理。 也许你可能会使用的方法之一 我上面提到的。 ,另外,您可能希望 提升一些颜色 并把那些出。 所以,现在我们已经改变了像素 色彩,接下来我们只需要编写他们 在到该扫描线,逐个像素。 并再次,你要回头 到copy.c,如果你还没有被复制 它已经,并期待在fwrite的 函数,它接受数据,一个指针 到包含该字节的结构 你是从,大小阅读 的项目,项目的数目, 然后outptr - 这些文件的目的。 当您在像素写,你会 还必须在填充写。 什么是填充? 那么,每一个像素RGBT 是3字节长。 但是,扫描线为位图图像 必须的4个字节的倍数。 如果象素的数目不是 多四个,那么我们就需要添加 这种填充。 填充,只需0表示。 那么,我们该如何写,或读这个? 嗯,事实证明,你不能 其实用fread填充,但你可以 计算。 在这种情况下,线索和判决 具有相同的宽度,所以 填充是相同的。 和填充,因为你会看到 在copy.c,计算 用下面的公式 - bi.biWidth倍的sizeof(RGBTRIPLE)会 给我们多少字节的bmp 有每一行中。 从那里,模数和减法 与4可以计算出 许多字节必须被添加,使得 在字节倍数 每一行是4。 现在,我们有公式 我们多么需要填充,现在 我们可以写它。 现在,我之前提到的, 填充仅仅是0。 因此,在这种情况下,我们只是把 一个字符,在这种情况下为0,进入我们 outptr - 我们的输出文件。 所以这只能说是的fputc 0,逗号outptr。 所以,虽然我们一直在阅读到我们的 文件,文件I / O一直跟踪我们 在与一些这些文件的位置 调用的文件位置指示器。 把它看成是一个光标。 基本上,它前进的每一次 我们FREAD,但我们有 控制了这一点。 如果要移动的文件位置指示器, 您可以使用函数fseek的。 其中inptr表示文件 您正在寻找的指针, 量的字节数,你 要移动光标,然后从 涉及的基准点 从光标所在处。 如果传入SEEK_CUR,那 表示当前 在文件中的位置。 或者您可以使用其他一些参数。 所以,我们可能要使用FSEEK跳过 在文件中的填充。 再次,如果你坚持,有 的,在copy.c.一个例子 所以,现在我们已经打开的文件, 的线索,并判决。 我们已经更新了头信息 我们的判决,因为每 位图需要的标头。 我们然后读入线索的 扫描线,逐个像素,改变 每一个颜色的需要,并 写那些进入 判决,逐像素。 一旦你打开的判决,你可以看到谁 罪魁祸首,还是什么秘密 消息。 我的名字是Zamyla,并 这是侦探小说。