[Powered by Google Translate] [Tutorial - Set Problema 4] [Zamyla Chan - Harvard University] [Esta es CS50. - CS50.TV] Está bien. Hola a todos y bienvenidos a Tutorial 4. Hoy nuestro conjunto de procesadores es Forensics. Forense es un conjunto de procesadores muy divertido que consiste en tratar con archivos de mapa de bits para descubrir que ha cometido un crimen. A continuación, vamos a cambiar el tamaño de algunos archivos de mapa de bits, entonces nosotros también vamos a hacer frente a una parte muy divertido llamado Recuperar, en el que estamos, básicamente, entregó una tarjeta de memoria en el que alguien ha borrado accidentalmente todos sus archivos, y se nos pide que recuperar esos archivos. Pero primero, antes de entrar en el conjunto de procesadores, realmente sólo quiero felicitar a todo el mundo. Estamos a punto en el punto medio de este curso. Quiz 0 está detrás de nosotros, y estamos en pset4, por lo que en esencia, estamos a mitad de camino. Hemos recorrido un largo camino si uno mira hacia atrás a sus conjuntos de procesadores, pset0 y pset1, así que felicitarse por eso, y vamos a entrar en algunas cosas realmente divertidas. Así que nuestra caja de herramientas para este conjunto de procesadores, de nuevo, en lugar de ejecutar sudo yum-y update, estamos en condiciones de ejecutar sólo update50 si usted está en la versión 17.3 y superior del aparato. Así que asegúrese de ejecutar update50 - es un fácil mucho, unos pocos caracteres menos - para asegurarse de que usted está en la última versión del aparato. Sobre todo es importante update50 cuando empezamos a usar CS50 Check. Así que asegúrate de que lo haces. Para todas las secciones de este conjunto de procesadores, vamos a estar tratando con entradas y salidas de archivos, archivar I / O. Vamos a ir a través de una gran cantidad de programas que tienen que ver con los arreglos apunta a archivos y cosas por el estilo, por lo que queremos asegurarnos de que estamos muy familiarizados y cómodos tratar con la forma de entrada y salida en los archivos. En el código de distribución para el conjunto de procesadores es un archivo llamado copy.c, y eso es lo que vamos a encontrar va a ser muy útil para nosotros porque vamos a terminar copiando el archivo copy.c y sólo se modifican ligeramente para ser capaz de lograr los primero 2 partes del conjunto de problemas. Y entonces, como he dicho antes, se trata de mapas de bits, así como JPEG. Así que en realidad la comprensión de la estructura de cómo se organizan los archivos, cómo realmente podemos traducir el 0 y 1 en las estructuras y las cosas que en realidad podemos entender e interpretar y editar, que va a ser muy importante, así que ir en JPEG y archivos de mapa de bits y la comprensión de la estructura de esos. Pset4, como de costumbre, comienza con una sección de preguntas. Los que se ocupará de archivo de E / S y conseguir que acostumbrados a eso. A continuación, la parte 1 es Quién lo hizo, en el que se te da un archivo de mapa de bits que se ve un poco como puntos rojos por todas partes. Y básicamente lo que vamos a hacer es tomar este archivo y editarlo sólo ligeramente en una versión que se puede leer. Básicamente, una vez que terminemos, vamos a tener el mismo archivo, excepto que será capaz de ver el mensaje oculto escondido por todos los puntos rojos. Entonces Resize es un programa que, dado un archivo y luego se da el nombre del archivo que se envía y se le da un número, así, realidad que cambia el tamaño de mapa de bits que valor entero. Entonces, por último, tenemos el conjunto de procesadores Recover. Se nos ha dado una tarjeta de memoria y luego tener que recuperar todas las fotos que han sido borrados accidentalmente, pero, como vamos a aprender, no elimina realmente y se elimina del archivo; simplemente un poco perdido en el que se encontraban en el archivo, pero vamos a recuperar eso. Grande. Así que va en el archivo de E / S en concreto, se trata de toda una lista de funciones que se va a utilizar. Ya has visto un poco los fundamentos de fopen, fread, fwrite, y pero vamos a profundizar en algún archivo de E / S funciona como fputc, en el que acaba de escribir un carácter a la vez, a fseek, donde se mueve el tipo de indicador de posición del fichero hacia delante y hacia atrás, y luego algunos otros. Pero vamos a entrar en eso un poco más tarde, durante el conjunto de procesadores. Así que primero, sólo para entrar en el archivo de E / S antes de entrar en el conjunto de procesadores, para abrir un archivo, por ejemplo, lo que tienes que hacer es establecer realmente un puntero a ese archivo. Así que tenemos un puntero FILE *. En este caso, estoy llamándolo un puntero porque eso va a ser mi infile. Así que voy a utilizar la función fopen y luego el nombre del archivo y entonces el modo en el que yo voy a estar tratando con el archivo. Así que hay "r" en este caso para la lectura, "w" para escritura, y luego "a" para anexar. Por ejemplo, cuando usted está tratando con un infile y todo lo que quieres hacer es leer los bits y los bytes almacenados allí, entonces usted está probablemente va a querer utilizar "r" como su modo. Cuando quiera escribir en realidad, una especie de hacer un nuevo archivo, entonces lo que vamos a hacer es que vamos a abrir el nuevo archivo y el uso de la "w" modo de escritura. Así que cuando usted está en realidad la lectura en los archivos, la estructura es la siguiente. En primer lugar se incluye el puntero a la estructura que contiene los bytes que usted está leyendo. Así que va a ser la ubicación final de los bytes que se está leyendo. Estás pasando luego a indicar el tamaño, al igual que, básicamente, la cantidad de bytes su programa tiene que leer en el archivo, el tamaño, básicamente, un elemento es, y entonces usted va a especificar cuántos elementos que desea leer. Y finalmente, usted tiene que saber dónde usted está leyendo, así que eso va a ser el puntero en. I codificados por color estos porque fread es también muy similar a fwrite, a menos que usted quiere asegurarse de que se utiliza el orden correcto, asegurarse de que en realidad estás escribiendo o leyendo desde el archivo correcto. Así que, como antes, si tenemos el tamaño del elemento, así como el número de elementos, entonces podemos jugar aquí un poco. Decir que tengo una estructura PERRO Y entonces quiero leer dos perros a la vez. Lo que podría hacer es decir el tamaño de un elemento que va a ser del tamaño de un perro y yo voy a leer realmente dos de ellos. Por otra parte, lo que podría hacer es decir que sólo voy a leer uno de los elementos y que un elemento va a ser el tamaño de dos perros. Así que eso es análoga cómo puede tipo de juego un poco con el tamaño y el número de dependiendo de lo que es más intuitivo para usted. Está bien. Ahora llegamos a los archivos de escritura. Si desea escribir un archivo, el primer argumento es en realidad donde usted está leyendo. Así que eso es, básicamente, los datos que se van a escribir en el fichero, que es el puntero al final. Así que cuando usted está tratando con el conjunto de procesadores, asegúrese de que no se confundan. Tal vez tener el lado definiciones a lado. Puede tirar de las definiciones en el manual tecleando man y fwrite, por ejemplo, en la terminal, o puede referirse a esta diapositiva y asegúrese de que está utilizando la correcta. Así que de nuevo, por fwrite, cuando usted tiene un archivo que se desea escribir en, que va a ser el último argumento y eso va a ser un puntero a ese archivo. Así que eso es lo que tratamos de escribir tal vez varios bytes a la vez, pero dice que quiere escribir justo en sólo un carácter único. Como veremos más adelante en este ejemplo, en los mapas de bits que tendremos que usar eso. Es entonces cuando podemos utilizar fputc, esencialmente sólo poner un carácter a la vez, chr, en el puntero de archivo, y ese es nuestro puntero a cabo allí. Así que cada vez que buscar o escribir en un archivo, el archivo es no perder de vista donde estamos. Así que es una especie de cursor, el indicador de posición del archivo. Y así, cada vez que escribimos o leemos de nuevo en un archivo, el archivo realmente recuerda donde está, y por lo que continúa desde donde está el cursor. Esto puede ser beneficioso cuando se quiere, por ejemplo, leer en una cierta cantidad para hacer algo y luego leer en las siguientes cantidades, pero a veces puede ser que desee volver o en realidad parten de un valor de referencia determinado. Entonces la función fseek, lo que hace es que nos permite mover el cursor en un determinado archivo un cierto número de bytes. Y entonces lo que tenemos que hacer es especificar que el valor de referencia es. Así que, o se mueve hacia delante o hacia atrás desde la posición del cursor en la actualidad es, o se puede especificar que solo debe moverse desde el principio del archivo o desde el final del archivo. Y por lo que puede pasar en valores negativos o positivos a cantidad, y que clase de mover el cursor hacia adelante o hacia atrás. Antes de entrar en los conjuntos de procesadores otras preguntas en el archivo I / O? Bien. Al entrar en más ejemplos, no dude en dejar de hacer preguntas. Así que en Whodunit, te entregó un archivo de mapa de bits similar a esta red en la diapositiva, y parece que esto - un montón de puntos rojos - y no se sabe muy bien lo que está escrito. Si usted escudriña, usted puede ser capaz de ver un ligero color azulado en el interior del centro. En esencia, eso es donde el texto se almacena. Hubo un asesinato que ocurrió, y tenemos que averiguar quién lo hizo. Con el fin de hacer eso, tenemos que convertir esta especie de imagen en un formato legible. Si ustedes he encontrado esto, a veces no habría kits pequeños donde tendría una lupa con una capa de color rojo. ¿Alguien? Si. Así que sería algo como esto sola mano, usted tendría una lupa con la película de color rojo sobre él, lo pondría sobre la imagen, y que sería capaz de ver el mensaje oculto en ella. No tenemos una lupa con película rojo, así que en vez que vamos a la clase de crear nuestro propio en este conjunto de procesadores. Y así, el usuario va a whodunit entrada, entonces la pista,. Bmp, así que esa es la infile, ese es el mensaje de punto rojo, y entonces ellos están diciendo verdict.bmp va a ser nuestro archivo de salida. Así que va a crear una imagen de mapa de bits similar a la idea de una excepto en un formato legible en el que podemos ver el mensaje oculto. Ya que vamos a estar tratando con la edición y manipulación de mapas de bits de algún tipo, vamos a clase de buceo en en la estructura de estos archivos de mapa de bits. Fuimos poco estas un poco en la conferencia, pero vamos a ver en ellos un poco más. Los mapas de bits son esencialmente sólo un arreglo de bytes donde hemos especificado qué significa lo bytes. Así que aquí es algo así como un mapa de la imagen de mapa de bits diciendo que se inicia con algunos archivos de cabecera, se inicia con un poco de información en ese país. Ya ves que a eso de byte número 14 se indica el tamaño de la imagen de mapa de bits, y se continúa. Pero lo que realmente estamos interesados ​​aquí está empezando alrededor del número de bytes 54. Tenemos estos triples RGB. Lo que va a hacer es contener los píxeles reales, los valores de color. Todo lo anterior que en la cabecera es información correspondiente al tamaño de la imagen, la anchura de la imagen, y la altura. Cuando entramos en el relleno más tarde, vamos a ver por qué el tamaño de la imagen puede ser diferente de la anchura o la altura. Así que para representar estos - estas imágenes de mapa de bits son secuencias de bytes - lo que podemos hacer es decir bien, yo voy a recordar que en el índice 14, ahí es donde el tamaño es, por ejemplo, pero en cambio lo que vamos a hacer para que esto sea más fácil está encapsulado en una estructura. Y así tenemos dos estructuras hechas para nosotros, un BITMAPFILEHEADER y un BITMAPINFOHEADER, y así cada vez que leemos a ese archivo, por defecto que va a ir en orden, y lo que para ella también va a rellenar en variables tales como biWidth y biSize. Y, finalmente, cada píxel está representado por tres bytes. La primera es la cantidad de azul en el píxel, el segundo es la cantidad de verde, y finalmente, la cantidad de rojo, donde 0 es esencialmente no verde azul o no o no roja y luego ff es el valor máximo. Estos son valores hexadecimales. Así que si tenemos ff0000, entonces corresponde a la cantidad máxima de azul y luego no hay verde y rojo no, es así, que nos daría un píxel azul. Entonces, si tenemos toda ff en todos los terrenos, entonces eso significa que tenemos un pixel blanco. Esto es un poco contrario a lo general, cuando decimos RGB. En realidad va BGR. Así que si realmente se ven en un ejemplo de una imagen de mapa de bits - quiero un tirón aquí. Es un poco pequeña. Estoy un acercamiento, y podemos ver que está pixelada. Parece que los bloques de color. Usted tiene bloques blancos y luego los bloques rojos. Si juegas en Microsoft Paint, por ejemplo, usted podría hacer algo así básicamente por pintar algunos cuadrados en un orden específico. Así que lo que se traduce en el mapa de bits es la siguiente. Aquí tenemos primero píxeles blancos, que son todas las 6 f, y entonces tenemos píxeles rojos, indicado por 0000ff. Y así, la secuencia de bytes que tenemos indica cómo la imagen de mapa de bits se va a ver. Así que lo que hemos hecho aquí es sólo por escrito con todos esos bytes y después se colorea en rojo para que pueda clase de ver, si usted escudriña un poco, cómo ese tipo de indica una cara sonriente. La forma en que el trabajo de las imágenes de mapa de bits que es básicamente lo imaginamos como una cuadrícula. Y así, de forma predeterminada, cada fila de la rejilla tiene que ser un múltiplo de 4 bytes. Si nos fijamos en una imagen de mapa de bits, que está llenando cada valor. Por ejemplo, usted podría tener un rojo por aquí, un verde aquí, un azul aquí, pero usted tiene que asegurarse de que la imagen se completa con un múltiplo de cuatro bytes. Así que si quiero que mi imagen sea tres cuadras de ancho, entonces yo tendría que poner un valor vacío en el último para que sea un múltiplo de cuatro. Así que me gustaría añadir algo en lo que estamos llamando relleno. Yo sólo voy a indicar que hay con una x. Ahora decimos que queremos una imagen que es de 7 píxeles de largo, por ejemplo. Tenemos 1, 2, 3, 4, 5, 6, 7, y todo eso se rellena con el color. La forma en que las imágenes de mapa de bits funciona es que necesitamos una octava. Ahora tenemos 1, 2, 3, 4, 5, 6, 7. Necesitamos 8 espacios para la imagen de mapa de bits a leer correctamente. Así que lo que tenemos que hacer es añadir en tan sólo un poco de relleno para asegurarse de que todas las anchuras son uniformes y que todas las anchuras son un múltiplo de 4. Y así se ha indicado anteriormente, el relleno como una X o una línea ondulada, pero en las imágenes de mapa de bits reales el relleno se indica mediante un 0 hexadecimal. Así que sería un personaje único, 0. Lo que podría ser útil es el comando xxd. Lo que hace es en realidad muestra que, al igual que similar a lo que hacía antes con el smiley cuando en realidad lo que imprime cada color sería para el píxel y luego un código de colores, cuando se ejecuta xxd con los siguientes comandos, entonces en realidad se imprimirá lo que los colores son para aquellos píxeles. Lo que tienes que hacer es indicar aquí que, al igual que la s-54 dice que yo voy a empezar por el byte 54a porque antes de eso, recuerde que si echamos la vista atrás para el mapa de los mapas de bits, esa es toda la información de cabecera y cosas por el estilo. Pero lo que realmente importa es los píxeles reales que indican el color. Por lo tanto añadiendo en esa bandera,-s 54, entonces somos capaces de ver los valores de color. Y no te preocupes por las banderas complicadas y cosas por el estilo. En la especificación del conjunto de problemas, tendrá instrucciones sobre cómo utilizar xxd para mostrar los píxeles. Así que si usted ve aquí, es como que se parece a una caja verde, esto es poca cosa. He codificado por colores como el 00ff00 básicamente diciendo que no azul, mucho verde y rojo no. Así que corresponde a verde. Como se ve aquí, vemos un rectángulo verde. Este rectángulo verde está a sólo 3 píxeles de ancho, por lo que entonces lo que tenemos que hacer para asegurarse de que la imagen es un múltiplo de 4 de ancho es añadir en un acolchado adicional. Y entonces así es como se ve estos 0s aquí. En realidad, esto será el resultado de su conjunto de procesadores de tamaño, esencialmente tomando el pequeño mapa de bits y luego ampliarlo por 4. Y así, lo que vemos es que en realidad esta imagen es de 12 píxeles de ancho, pero 12 es un múltiplo de 4, por lo que en realidad no veo ninguna 0s al final porque no es necesario añadir ningún porque está totalmente acolchado. No tiene sala más. Bien. Cualquier pregunta acerca de relleno? Bien. Cool. Como he mencionado antes, los mapas de bits son más que una secuencia de bytes. Y así, lo que tenemos es en lugar de tener que llevar un registro de exactamente qué número de bytes corresponde a un elemento específico, que en realidad han creado una estructura para representar eso. Así que lo que tenemos es una estructura RGBTRIPLE. Siempre que tenga una instancia de un triple RGB, porque se trata de un tipo struct define, entonces usted puede acceder a la variable rgbtBlue, de manera similar las variables de verde y rojo, que indican la cantidad de azul, verde y rojo respectivamente, que usted tiene. Así que si tenemos la variable de azul a 0, el conjunto verde a ff, que es el valor máximo que puede tener, y entonces la variable rojo ajustado a 0, entonces, ¿qué color sería el particular triples RGB representa? >> [Estudiante] Green. Green. Exactamente. Va a ser útil saber que cada vez que tenga una instancia de un triple RGB, en realidad se puede acceder a la cantidad de color - azul, verde y rojo - por separado. Ahora que hemos hablado de la estructura de eso, vamos a echar un vistazo al archivo BMP. Estas son estructuras hechas para usted. Aquí tenemos una estructura BITMAPFILEHEADER. De interés es el tamaño. Más tarde, tenemos la información de cabecera, que tiene un par de cosas más que son interesantes para nosotros, a saber, el tamaño, la anchura, y la altura. Como vamos a entrar en más tarde, cuando se lee en el archivo, se lee automáticamente en porque hemos creado la orden de ser el mismo. Así la biSize contendrá los bytes adecuadas que se corresponden con el tamaño real de la imagen. Y aquí, por último, como ya hemos hablado, tenemos el typedef struct RGBTRIPLE. Tenemos una rgbtBlue, verde y rojo asociado a él. Grande. Bien. Ahora que entendemos los mapas de bits un poco, entendemos que tenemos un archivo de cabecera y una cabecera de información de la misma y después de eso, tenemos las cosas interesantes de los colores, y los colores están representados por las estructuras RGBTRIPLE, y los que, a su vez, tiene tres valores asociados a la azul, el verde y el rojo. Así que ahora, podemos pensar en clase de recuperar un poco. Lo siento. Piense Whodunit. Cuando tenemos nuestro archivo de pista, entonces lo que queremos hacer es leer a ella pixel por pixel y entonces de alguna manera cambiar los píxeles de manera que podamos dar salida a un formato legible. Y así, para dar salida, vamos a escribir pixel por pixel en el archivo verdict.bmp. Eso es un poco mucho para hacer. Nos damos cuenta de eso. Así que lo que hemos hecho es que hemos hecho le proporcionó copy.c. Lo que hace es copy.c sólo hace una copia exacta de un archivo de mapa de bits dado y luego la emite. Así que esto ya se abre el archivo para usted, se lee en pixel por pixel, y entonces se escribe en un archivo de salida en. Vamos a echar un vistazo a eso. Esta es asegurar el uso adecuado, obtener los nombres de los archivos aqui. Lo que esto hace es que establece el archivo de entrada sea lo que hemos pasado en el infile aquí, que es nuestro segundo argumento de línea de comandos. Se asegura de que podamos abrir el archivo. Cheques para asegurarnos de que podemos hacer un nuevo archivo de salida aquí. Entonces, ¿qué hace este aquí, sólo, básicamente, comienza a leer en el archivo de mapa de bits desde el principio. El comienzo, como sabemos, contiene el BITMAPFILEHEADER, y por lo que esas secuencias de bits directamente completará el BITMAPFILEHEADER. Así que lo que tenemos aquí está diciendo que bf BITMAPFILEHEADER - esa es nuestra nueva variable de tipo BITMAPFILEHEADER - vamos a poner dentro bf lo que leemos de puntero, que es nuestro infile. ¿Cuánto leemos? Leemos en la cantidad de bytes que necesitamos para contener el BITMAPFILEHEADER conjunto. Del mismo modo, eso es lo que hacemos por la información de cabecera. Así que seguimos a lo largo de nuestro archivo en el infile, y nos estamos leyendo los bits y bytes, y los estamos conectando directamente en en estos casos de las variables que estamos haciendo. Aquí sólo estamos asegurando que el mapa de bits es un mapa de bits. Ahora tenemos un archivo de salida, ¿no? Así que tal y como está cuando lo creamos, es esencialmente vacío. Así que tenemos que crear un nuevo mapa de bits, básicamente, a partir de cero. Lo que hacemos es que tenemos que asegurarnos de que copiar en el archivo de cabecera y la información de cabecera al igual que el infile tiene. Lo que hacemos es escribir - y recuerde que bf es la variable de BITMAPFILEHEADER tipo, así que lo que hacemos es que sólo tiene que utilizar ese contenido para escribir en el archivo de salida. En este sentido, recuerdo que hablamos sobre el relleno, cómo es importante asegurarse de que la cantidad de píxeles que tenemos es un múltiplo de 4. Esta es una fórmula muy útil para calcular la cantidad de relleno que tiene dada la anchura de su archivo. Yo quiero que ustedes recuerden que en copy.c tenemos una fórmula para el cálculo de relleno. ¿De acuerdo? Así que todo el mundo recuerda eso. Grande. Entonces, ¿qué hace copy.c siguiente es que se repite en todas las líneas de exploración. Pasa a través de las filas primera y luego almacena cada triple que se lee y entonces se escribe en el archivo de salida. Así que aquí estamos leyendo sólo un triple de RGB a la vez y luego poner que Triple mismos en el archivo de salida. La parte difícil es que el relleno no es un triple RGB, y por lo tanto no podemos leer esa cantidad de relleno triples RGB. Lo que tenemos que hacer es en realidad sólo mover nuestro indicador de posición del fichero, desplazar el cursor, al tipo de saltarse todo el relleno de modo que estamos en la fila siguiente. Y entonces lo que hace es copiar muestra cómo es posible que desee agregar el relleno. Para ello hemos calculado la cantidad de relleno que necesitamos, lo que significa que necesitamos acolchado número de 0s. Lo que hace es un bucle que sitúa el número de 0s acolchado en nuestro archivo de salida. Y, finalmente, se cierra ambos archivos. Se cierra el infile así como el archivo de salida. Así es como funciona copy.c, y eso va a ser muy útil. En lugar de simplemente en realidad directamente copiar y pegar o simplemente mirarlo y escribir lo que quieras, puede que desee para ejecutar este comando en la terminal, cp copy.c whodunit.c, lo que creará un nuevo archivo, whodunit.c, que incluye el contenido exactamente igual que copia lo hace. Así que lo que podemos hacer es usar eso como una base sobre la cual construir y editar para nuestro archivo novela policíaca. Estas son nuestras tareas pendientes que hacer para Whodunit, pero ¿qué copy.c en realidad se encarga de la mayor parte de ellos para nosotros. Así que todo lo que tenemos que hacer ahora es cambiar los píxeles según sea necesario para hacer realidad el archivo legible. Recuerde que para un píxel dado, triple, así que para una variable dada de RGBTRIPLE tipo, puede acceder a los valores de azul, verde y rojo. Eso va a ser muy útil porque si se puede acceder a ellos, que significa que también se puede comprobar, y eso significa que también se puede cambiar. Así que cuando volvimos a nuestro ejemplo rojo lupa, básicamente, que actuaba como una especie de filtro para nosotros. Así que lo que quiero hacer es que queremos filtrar todos los triples que vienen pulg Hay varias maneras de hacer esto. Básicamente, usted puede tener cualquier tipo de filtro que desee. Tal vez usted quiere cambiar todos los píxeles rojos o tal vez desea cambiar un píxel de color a un color diferente. Eso depende de ti. Recuerde que usted puede ver que el color del píxel es y también se puede cambiar a medida que estás pasando. Bien. Así que eso es Whodunit. Una vez que ejecute Quién lo hizo, usted sabrá quién es el culpable del crimen era. Ahora vamos a ir a cambiar el tamaño. Vamos a todavía estar tratando con mapas de bits. Lo que vamos a hacer es que vamos a tener un mapa de bits de entrada y luego vamos a pasar en un número y obtener un mapa de bits archivosalida donde eso es básicamente nuestro infile escalado por n. Di mi archivo era sólo un pixel grande. Entonces, si mi n fue de 3, escalado por 3, entonces me gustaría repetir ese pixel n número de veces, por lo que 3 veces, y luego también reduce la escala 3 veces también. Así que ya ves que estoy escalando tanto vertical como horizontalmente. Y he aquí un ejemplo. Si tiene n = 2, se ve que el píxel azul principio no repitió dos veces tanto horizontal como verticalmente dos veces. Y luego que sigue adelante, y para que tenga una ampliación directa de la imagen original en dos. Así que si nos íbamos a detalle el pseudocódigo para esto, queremos abrir el archivo. Y luego, a sabiendas de que si volvemos aquí, vemos que la anchura para el archivo de salida que va a ser diferente de la anchura de la infile. ¿Qué significa eso? Eso significa que nuestra información de cabecera se va a cambiar. ¿Y qué vamos a querer hacer es actualizar la información de la cabecera, sabiendo que cuando leemos en los archivos si usted está trabajando en el marco copy.c, ya tenemos una variable que indica cuál es el tamaño es y cosas así. Así que una vez conseguido eso, lo que puede querer hacer es cambiar esas variables particulares. Recuerde, si usted tiene una estructura, cómo se accede a las variables dentro de eso. Se utiliza el operador punto, ¿no? Así que con eso, ya sabes que tendrás que cambiar la información de la cabecera. Así que esta es sólo una lista de los elementos reales que se van a cambiar en el archivo. El tamaño del archivo que se va a cambiar, la imagen, así como la anchura y la altura. Así que volver al mapa de los mapas de bits, ver si se trata de la cabecera del archivo o la información de cabecera que contiene esa información y luego cambiar según sea necesario. Una vez más, por ejemplo cp copy.c resize.c. Eso significa que resize.c ahora contiene todo lo que está contenido en el interior copia copia porque nos proporciona una forma de lectura en línea de exploración a cada píxel a píxel. Sólo que ahora, en vez de cambiar los valores como lo hicimos en Whodunit, lo que queremos hacer es que queremos escribir en varios píxeles mientras nuestro n es mayor que 1. Entonces lo que quiero hacer es lo queremos estirar horizontalmente por n, así como que se extienden verticalmente por n. ¿Cómo podemos hacer esto? Digamos que su n es 2 y que tiene esta dado infile. El cursor se va a empezar por el primero, y lo que quiere hacer si n es 2, que desea imprimir en 2 de ellos. Así que imprimir en dos de ellos. A continuación, el cursor se va a pasar a la siguiente píxel, que es el rojo, y que va a imprimir 2 de esos rojos, añadiendo que en lo que ha hecho antes. A continuación, el cursor se moverá a la siguiente píxel y dibujar en 2 de ellos. Si se mira de nuevo a la copy.c marco, lo que esto hace aquí se crea una nueva instancia de un triple RGB, una nueva variable llamada triple. Y aquí cuando lee en él, lo hace desde el 1 infile RGBTRIPLE y se almacena en el interior de esa variable triple. Así que en realidad tiene una variable que representa ese píxel en particular. Entonces, cuando usted escribe, lo que puede querer hacer es encerrar la declaración fwrite en un bucle for que escribe en su archivo de salida tantas veces como sea necesario. Eso es bastante simple. Así, básicamente, repita el proceso de escritura n número de veces para escalar horizontalmente. Pero tenemos que recordar que nuestro relleno se va a cambiar. Antes, decir que tuvimos algo de longitud 3. Entonces nos volveríamos a añadir en el relleno? Sólo uno más para que sea un múltiplo de 4. Pero decir que estamos escalando esta imagen en particular por n = 2. Entonces ¿cuántos píxeles azules tendríamos al final? Tendríamos 6. 1, 2, 3, 4, 5, 6. Está bien. 6 no es un múltiplo de 4. ¿Cuál es el más cercano múltiplo de 4? Eso va a ser 8. Así que estamos realmente va a tener dos caracteres de relleno allí. ¿Alguien recuerda si tenemos una fórmula para calcular el relleno y dónde podría estar? [Respuesta de los estudiantes inaudible] >> Sí, copy.c. Derecha. Hay una fórmula en copy.c para calcular la cantidad de relleno que tiene dado una anchura particular de la imagen de mapa de bits. Así que va a ser útil cuando se necesita agregar en una cierta cantidad de relleno de entender realmente a cabo el relleno tiene que agregar. Pero una nota, sin embargo, es que usted quiere asegurarse de que usted está usando el tamaño correcto. Sólo ten cuidado porque estás básicamente va a estar tratando con dos imágenes de mapa de bits. Usted quiere asegurarse de que está utilizando la correcta. Cuando usted está calculando el relleno para el archivo de salida, que desea utilizar todo el ancho del archivo de salida y no el ancho de la anterior. Grande. Ese tipo de estiramiento se hace cargo de una imagen de mapa de bits total horizontalmente. Pero lo que quiero hacer es realmente estirar verticalmente también. Esto va a ser un poco más complicado porque cuando hemos terminado de copiar una fila y escribir esa fila, nuestro cursor va a estar en el extremo. Así que si volvemos a leer, entonces sólo va a leer en la siguiente línea. Así que lo que quiero hacer es una especie de encontrar alguna forma de copiar las filas de nuevo o simplemente tomar ese tipo de fila y luego volver a escribir de nuevo. Como tipo de alusión, hay varias maneras de hacer esto. Lo que podría hacer es que estás pasando y la lectura a través de la línea de exploración especial y cambiarlo según sea necesario y todo tipo de tienda de los píxeles en una matriz. Luego, más tarde usted sabe que usted tendrá que imprimir la matriz de nuevo, y por lo que sólo se puede utilizar la matriz para hacer eso. Otra manera de hacerlo es que se podría copiar una fila hacia abajo, Entiendo que tiene que copiar de nuevo, por lo que en realidad mueve el cursor, y que va a utilizar el método fseek. Usted puede mover el cursor hasta el final de nuevo y repita el proceso de copia de nuevo. Así que si nuestro número de escala es n, entonces ¿cuántas veces tenemos que volver y volver a escribir una línea? >> [Estudiante] n - 1. >> Sí, perfecto. n - 1. Lo hemos hecho ya una vez, por lo que a continuación vamos a querer repetir el proceso de vuelta atrás n - 1 cantidad de veces. Bien. Así que ahí tienen la función de cambio de tamaño. Ahora podemos llegar a una parte muy divertido, mi favorito conjunto de procesadores, que es Recover. En lugar de mapas de bits, esta vez estamos tratando con archivos JPEG. Estamos en realidad no da un solo archivo de imágenes JPEG, y cuando nos den básicamente un formato raw tarjeta de memoria. Y por lo que este contiene un poco de información de valores y la basura en el principio, y luego empieza y tiene un montón de archivos JPEG. Sin embargo, nos entregó una tarjeta en la que ha borrado las fotos; en esencia, nos hemos olvidado de donde las fotos se encuentran dentro de la tarjeta. Así que nuestra tarea de recuperar es ir a través de este formato de tarjeta y encontrar esas fotos otra vez. Por suerte, la estructura de archivos JPEG y el archivo de la tarjeta es un poco de ayuda. Que sin duda podría haber sido un poco más complicado si no fuera en este formato en particular. Cada archivo JPEG en realidad comienza con dos secuencias posibles, enumerados anteriormente. Básicamente, cada vez que tenga un nuevo archivo JPEG, que comienza con la secuencia de cualquiera de ffd8 FFE0 o el otro, ffd8 ffe1. Otra cosa útil es saber que los archivos JPEG se almacenan de forma contigua. Así que cada vez que un archivo JPEG termina, el otro comienza. Así que no hay ningún tipo de en-entre los valores de ese país. Una vez que llegue el inicio de un archivo JPEG, si ya has estado leyendo un archivo JPEG, sabes que has llegado al final de la anterior y el comienzo de la siguiente. Para tipo de visualizar esto, hice un esquema. Otra cosa sobre los archivos JPEG es que podemos leer en las secuencias de 512 bytes a la vez, de manera similar con el comienzo de la tarjeta. No necesitamos estar comprobando cada byte único, ya que sería un asco. Así que en vez, lo que podemos hacer es en realidad acabo de leer en 512 bytes a la vez y entonces, en lugar de comprobar entre los de esas porciones diminutas, sólo podemos comprobar el inicio de los 512 bytes. Esencialmente, en esta imagen, lo que se ve es en el comienzo de la tarjeta, tiene valores que no son realmente relevantes para los archivos JPEG en sí mismas. Pero entonces lo que tenemos es una estrella para indicar una de las dos secuencias de partida para un JPEG. Así que cada vez que vea una estrella, usted sabe que tiene un archivo JPEG. Y entonces todos los archivos JPEG va a ser un múltiplo de 512 bytes pero no necesariamente el mismo múltiplo. La forma en que usted sabe que usted ha golpeado otra JPEG es si se golpea otra estrella, otra secuencia de partida de bytes. Entonces, lo que tenemos aquí es que tenga el archivo JPEG rojo continúa hasta llegar a una estrella, que se indica mediante un color nuevo. Usted continúa y entonces golpeó otra estrella, que chocó con otro formato JPEG, continúa todo el camino hasta el final. Estás en la última foto aquí, el rosa. Ve hasta el final hasta llegar a la final del personaje archivo. Esto va a ser realmente útil. A pocos robos de balón principales aquí: El archivo de la tarjeta no se inicia con un archivo JPEG, pero una vez que comienza un JPEG, todos los archivos JPEG se almacenan lado a lado entre sí. Algunos pseudocódigo para la Recuperación. En primer lugar, vamos a abrir nuestro archivo de tarjeta, y que va a estar usando nuestro archivo de E / S funciones. Vamos a repetir el siguiente proceso hasta que hemos llegado al final del archivo. Vamos a leer 512 bytes a la vez. Y lo que quiero decir aquí es que vamos a guardarlo en un buffer, así que básicamente se aferran a esos 512 bytes hasta que sepamos exactamente qué hacer con ellos. Entonces lo que quiero hacer es que queremos comprobar si nos hemos topado con una estrella o no. Si nos hemos topado con una estrella, si hemos golpeado una de las secuencias de arranque, entonces sabemos que hemos alcanzado un nuevo archivo JPEG. Lo que usted querrá hacer es que vamos a querer crear un nuevo archivo en nuestro directorio pset4 para seguir haciendo ese archivo. Pero también, si ya hemos hecho un JPEG antes, entonces queremos acabar con ese archivo y empujar a la carpeta pset4, donde tendremos ese archivo guardado porque si no se especifica que hemos terminado ese archivo JPEG, a continuación, que básicamente tendrás una cantidad indeterminada. Los archivos JPEG no tendrá fin. Así que queremos asegurarnos de que cuando estamos leyendo en un archivo JPEG y escrito que, que se quiere cerrar específicamente que, para abrir el siguiente. Tendremos que desee comprobar varias cosas. Queremos comprobar si estamos en el comienzo de una nueva JPEG con nuestro buffer y también si ya ha encontrado un JPEG antes porque eso va a cambiar su proceso ligeramente. Así que después de pasar por todo el camino y le golpeó el final del archivo, entonces lo que usted querrá hacer es que usted quiere cerrar todos los archivos que estén abiertos. Esto probablemente será el último archivo JPEG que usted tiene, así como el archivo de tarjetas que usted ha estado tratando. El último obstáculo que tenemos que abordar es cómo hacer realidad un archivo JPEG y cómo en realidad lo empuja a la carpeta. El conjunto de procesadores requiere que cada JPEG que se encuentra estar en el siguiente formato, donde tienes el número. jpg. El número, incluso si es 0, lo llamamos 000.jpg. Cada vez que encuentre un archivo JPEG en el programa, usted va a querer darle un nombre en el orden en que se encuentre. ¿Qué quiere decir esto? Tenemos que tipo de seguimiento de cuántos hemos encontrado y lo que el número de cada JPEG debe ser. Aquí vamos a aprovechar la función sprintf. Al igual que printf, que sólo tipo de impresiones en un valor fuera de la terminal, sprintf imprime el archivo en la carpeta de salida. Y así lo que esto haría si tuviera sprintf, título, y luego la cadena allí, sería imprimir 2.jpg. Suponiendo que he cerrado mis archivos correctamente, que contiene el archivo que había estado escribiendo. Pero una cosa es que el código que tengo aquí no acaba de satisfacer lo que el conjunto de procesadores requiere. El conjunto de procesadores requiere que el segundo archivo JPEG debe ser nombrado 002 en vez de 2. Así que cuando se imprima el nombre, entonces tal vez usted puede ser que desee modificar ligeramente el marcador de posición. ¿Alguien recuerda cómo permitir espacios adicionales cuando escribamos algo? Si. >> [Estudiante] Se pone un 3 por ciento entre el signo y el 2. >> Sí, perfecto. Vas a poner un 3 en este caso porque queremos que el espacio para 3. 3d% probablemente le daría 002.jpg lugar de 2. El primer argumento en la función sprintf es en realidad una matriz de caracteres, que previamente sabía como cadenas. Aquellos voluntad, un poco más como un depósito temporal, sólo almacenar la cadena resultante. En realidad, no se trata de esto, sino que hay que incluir. Sabiendo que cada nombre de archivo tiene el número, que ocupa tres personajes, y entonces. jpg, ¿cuánto tiempo debe ser esta matriz? Tire a la basura un número. ¿Cuántos caracteres en el título, en el nombre? Así que hay tres hashtags, período, jpg. >> [Estudiante] 7. >> 7. No del todo. Vamos a querer 8 porque queremos permitir el terminador nulo también. Por último, sólo para alargar el proceso que se va a hacer para recuperar, usted tiene alguna información comienzo. Continuar hasta encontrar el inicio de un archivo JPEG, y que puede ser o bien una de las dos secuencias de partida. Tú sigue leyendo. Cada barra representa aquí 512 bytes. Usted siga leyendo, siga leyendo hasta que se encuentra con otra secuencia de arranque. Una vez conseguido eso, se termina el actual JPEG - en este caso, es el rojo, por lo que desea poner fin a eso. ¿Quieres sprintf el nombre de esa carpeta en su pset4, entonces usted quiere abrir una nueva JPEG y luego seguir leyendo hasta que se encuentra con el siguiente. Sigue leyendo, sigue leyendo, y, finalmente, con el tiempo, vas a llegar al final del archivo, y por lo que usted quiere cerrar la última JPEG que estabas trabajando, sprintf que en su carpeta pset4, y luego ver todas las fotos que has conseguido. Esas fotos son en realidad imágenes de CS50 personal, y aquí es donde viene la parte divertida bonificación del conjunto de procesadores se presenta en es que están compitiendo en sus secciones para encontrar la TFS en las fotos y tomarse fotos con ellos para probar que usted ha hecho el conjunto de procesadores y para que pueda ver que los miembros del personal están en las fotos. Así que toma imágenes con el personal. A veces tendrás que perseguirlos. Probablemente algunos de ellos tratará de huir de ti. Se toma fotos con ellos. Esto está en curso. No es exigible cuando el conjunto de procesadores es debido. El plazo se darán a conocer en la especificación. Entonces, junto con su sección, lo que lleva a la mayoría de la sección fotos con los miembros de la mayoría del personal se llevarán un premio bastante impresionante. Eso es una especie de incentivo para obtener su pset4 termine lo antes posible porque entonces usted puede ir al grano la caza de todos los diferentes miembros del personal CS50. Eso no es obligatoria, sin embargo, así una vez que las fotos, entonces ya ha terminado con pset4. Y he terminado con Tutorial 4, así que gracias a todos por venir. Buena suerte con Forense. [Aplauso] [CS50.TV]