Archivo

Entradas Etiquetadas ‘linea’

Recopilación de soluciones para los retos de #tuentiContest . Challenge #14

Lunes, 27 de Junio de 2011 Gaspar Fernández 2 comentarios

Últimamente he hablado acerca del I concurso de programación de Tuenti. Un concurso de programación Online que se llevó acabo durante la semana pasada (del 13 al 20 de Junio, muy mala fecha).

Podéis ver los enunciados de todos los problemas, con ejemplos sobre la entrada y salida (aunque a veces no hay que haerles mucho caso) en la web oficial del concurso, pero en Vidas Concurrentes lo encontramos todo en español.

Challenge #14 : Colors are beautiful

Nos dan una imagen para que la carguemos, y luego nos dirán una componente y un número de línea, para que hagamos la suma de esa componente a lo largo de toda la línea
Soluciones:

Si no estás en la lista y quieres plantear tu solución, deja un comentario con tu link !

Actualización 2011/06/28 08:30 : Añadida solución de @theom3ga
Actualización 2011/06/28 08:35 : Añadida solución de @ricardclau
Actualización 2011/07/03 01:49 : Añadida solución de @frisco82
Actualización 2011/07/03 13:45 : Añadida solución de @Rosapolis
Actualización 2011/07/14 14:55 : Añadida solución de @lagunex

#tuentiContest solución del Challenge 14 en C. Colours are beautiful

Lunes, 27 de Junio de 2011 Gaspar Fernández Sin comentarios

Presento aquí mi solución al reto 14, en el que nos pasan una imagen en BMP, y por la stdin nos dan una componente (R, G, B) y un número de línea. Tenemos que hacer la suma de los valores de esa componente a lo largo de la línea especificada, y luego sumar 1.

Para ello, vamos a valernos del post dedicado a la lectura de archivos BMP en C, esta será una de las aplicaciones que vamos a hacer.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>

#define STRSIZE 1000

typedef struct bmpFileHeader
{
  uint32_t size;
  uint16_t resv1;
  uint16_t resv2;
  uint32_t offset;
} bmpFileHeader;

typedef struct bmpInfoHeader
{
  uint32_t headersize;      /* DIB header size */
  uint32_t width;
  uint32_t height;
  uint16_t planes;         /* color planes */
  uint16_t bpp;            /* bits per pixel */
  uint32_t compress;
  uint32_t imgsize;    
  uint32_t bpmx;        /* X bits per meter */
  uint32_t bpmy;        /* Y bits per meter */
  uint32_t colors;      /* colors used */
  uint32_t imxtcolors;      /* important colors */
} bmpInfoHeader;

/* old function I made */
unsigned char *LoadBMP(char *filename, bmpInfoHeader *bInfoHeader);
int calculate_sum(bmpInfoHeader *info, unsigned char *img, char rgb, int line);

int main()
{
  bmpInfoHeader info;
  unsigned char *img;
  char bigstr[STRSIZE];
  int line_number;

  img=LoadBMP("trabaja.bmp", &info);

  while (fgets(bigstr, STRSIZE, stdin)!=NULL)
    {
      line_number=info.height-atoi(bigstr+1)-1; /* bmps are inverted. Line 0 is count*/
      printf("%d\n", calculate_sum(&info, img, bigstr[0],line_number));
    }

  return 0;
}

unsigned char *LoadBMP(char *filename, bmpInfoHeader *bInfoHeader)
{

  FILE *f;
  bmpFileHeader header;
  unsigned char *imgdata;
  uint16_t type;
  f=fopen (filename, "r");
  /* handle open error */
  fread(&type, sizeof(uint16_t), 1, f);
  if (type !=0x4D42)
    {
      fclose(f);
      return NULL;
    }
  fread(&header, sizeof(bmpFileHeader), 1, f);

  fread(bInfoHeader, sizeof(bmpInfoHeader), 1, f);
  imgdata=(unsigned char*)malloc(bInfoHeader->imgsize);
  fseek(f, header.offset, SEEK_SET);
  fread(imgdata, bInfoHeader->imgsize,1, f);
  fclose(f);

  return imgdata;
}

int calculate_sum(bmpInfoHeader *info, unsigned char *img, char rgb, int line)
{
  int i;
  int sum=0;
  int comp;
  char *bgr="BGR";
  char *tcomp=strchr(bgr, rgb);
  if (tcomp==NULL)
    return 0;

  comp=tcomp-bgr;

  for (i=0; i<info->width; i++)
    {
      sum+=img[3*(i+line*info->width)+comp];
    }
 
  return sum+1;
}

Ya que las cabeceras y la función LoadBMP() ya están analizadas en el post anterior. Analizaremos las funciones calculate_sum() y la principal.

En calculate_sum(), lo que hacemos es primero, obtener el número de la componente a extraer, ya que B=0, G=1, R=2, hallaremos la posición del carácter en la cadena, y si éste existe (tcomp!=NULL), en la variable comp almacenaremos dicha posición (como strchr devuelve un puntero a la parte de la cadena correspondiente, sólo tenemos que restar con la cadena con la que comparamos.
Luego, hacemos un for para recorrer todos los puntos de la línea, pero sólo leyendo los datos de la componente seleccionada. En cada iteración incrementaremos la variable sum para que nos devuelva la suma total de todos los pixels.

En la función principal, lo único que hacemos es cargar en memoria el BMP, y leer por la stdin la entrada propuesta Wxxx, donde W es la componente a leer (R,G,B) y xxx es el número de línea a leer. Desde main() invertimos la línea (como ya dijimos en los BMP, la imagen está boca abajo), por lo que en lugar de leer la línea Y, debemos leer la línea [ ALTO - Y - 1 ] (restamos 1 porque la primera línea es la 0).

Tal vez para hacer la función calculate_sum() más general, debería haber hecho la conversión de línea dentro de ésta (la conversión es algo interno), y la suma de 1 (es algo que nos pide el problema).

Jugando con ImageMagick (III): Colecciones, texto, y unión de efectos

Lunes, 6 de Septiembre de 2010 Gaspar Fernández Sin comentarios

El tercer post de la serie, anteriormente hablábamos de:

  1. Dimensiones, Captura, Color y Efectos
  2. Color (continuación) y Rotación

Juntando imágenes en una sola

Ahora, la cosa se anima, veremos cómo recopilar varias imágenes en el mismo archivo de imagen; habréis visto algún ejemplo en la entrega II, en los que muestro varias imágenes juntas:

variasPara ello usamos montage:

$ montage -tile 4×2 -geometry 200×160+1+0 taza1.jpg taza2.jpg taza3.jpg taza4.jpg hamburgueson1.jpg hamburgueson2.jpg hamburgueson3.jpg hamburgueson4.jpg varias.jpg

Donde, con el parámetro tile, especificamos la agrupación de las imágenes ancho x alto (4×2 en este caso) y con geometry, el tamaño de cada imagen 200×160 de máximo, con una separación de 1 pixel a los lados y ninguno verticalmente.

La imagen conserva su aspecto, pero de alto ocupa 160 pixels por lo que existe una pequeña separación.

Añadiendo texto

outSin imagen original, simplemente un texto en un archivo de imagen. Obtenido de la siguiente forma:

$ convert -background black -fill red -gravity center -font Verdana -pointsize 20 -size 200×80 caption:’Rojo sobre negro’ rojosobrenegro.png

Donde:

  • -background especifica el color de fondo
  • -fill especifica el color de primer plano
  • -gravity es la alineación, centrada, tanto horizontal como verticalmente.
  • -font indica el tipo de letra
  • -pointsize indica el tamaño de la letra
  • -size indica el tamaño de la imagen (porque no vamos a utilizar ninguna imagen de origen).
  • caption:’Texto’ con ello indicamos el texto

out1

$ convert -size 300×120 xc:rgb\(50,50,70\) -fill rgb\(90,150,200\) -gravity SouthEast -font helvetica -pointsize 25 -draw ‘text 10 2 “Poesía Binaria”‘ poesia_binaria.jpg

Donde incluimos el texto en una determinada posición: 10×2 desde la esquina inferior derecha (SouthEast), tipo de letra helvetica y tamaño 25; de fondo (50,50,70) y de color (90,150,200).

out2Ahora, aprovecharemos un poco más las capacidades de la orden draw. Para ello, dibujaremos un cuadro en negro dentro de la imagen (antena.jpg de dimensiones 314×300) a modo de marco (verde); luego trazaremos una línea horizontal de color blanco (rojo) en el borde del cuadro que acabamos de dibujar y tras ello escribiremos un texto (azul).

$ convert antena_2.jpg -gravity SouthEast -font helvetica -pointsize 25 -fill black -draw ‘rectangle 0,270 314,300′ -fill white -draw ‘line 0,270 314,270′ -draw ‘text 13 1 “Mi antena Wifi”‘ out.jpg

out3Ahora introduciremos el texto directamente en la imagen, pero para facilitar la lectura incluiremos una sobra en el texto.

$ convert antena_2.jpg -gravity North -font helvetica -pointsize 25 -fill black -draw ‘text 0 0 “Mi antena Wifi”‘ -fill white -draw ‘text 1 1 “Mi antena Wifi”‘ out.jpg

Podemos incluir de forma opcional -blur 1×1 (por ejemplo) para difumirar el texto que hace de sombra y suavizarla.

Juntando los efectos disponibles

Uno de los mejores ejemplos es el siguiente: http://www.imagemagick.org/Usage/thumbnails/ aunque encontramos cientos de webs con efectos preparados para ImageMagick:

Curioso e interesante (2): Fragmentación en Linux, WikiUnix, convertir documentos desde la línea de comando, Ubuntu más seguro que Windows by Dell

Domingo, 13 de Junio de 2010 Gaspar Fernández Sin comentarios

Estos días he estado un poco liado, pero he dejado varias pestañas del navegador abiertas con algunas curiosidades que he encontrado estos días y me han llamado la atención:

  • Lo leí en Muy Linux. Hay controversia en este tema… casi todos decimos que no es necesario, y otros dicen que sólo somos geeks talibanes que ocultamos las carencias de nuestro sistema operativo preferido; pero la realidad es que la fragmentación en los sistemas de archivos más populares de Linux es significativamente menor que en Windows. Podemos ver más información en: Why doesn’t Linux need defragmenting?
  • Conversor de documentos de OpenOffice desde la línea de comandos: unoconv. Es un script en python que nos permite hacer conversiones de documentos en cualquier formato soportado por OpenOffice (necesita OpenOffice instalado y pyUno). Esto nos permitirá por ejemplo automatizar la conversión de formatos.
  • WikiUnix: Es una gran wiki de referencia de comandos y características de los sistemas Unix; un proyecto de la Oficina de Software Libre de la Universidad de Cádiz.
  • Dell afirma que: Ubuntu es más seguro que Windows; mientras Dell, sigue recomendando insistentemente en su web Windows 7…
  • Microsoft se mofa del fondo de Google. Vale que Google se pasó, metiendo un fondo automáticamente, a modo de presentación de su nueva característica; a la gente no le suelen gustar los cambios. Pero Microsoft aprovecha la más mínima para meter baza. Ya vale con las cadenas de Televisión que muestran el logotipo de Windows o una imagen de Internet Explorar cada vez que emiten la imagen de un ordenador; o que invierta en product placement en series como Crónicas Vampíricas y en varios episodios, Jericho, Entre Fantasmas, Smallville, El Internado, Los Protegidos… qué pastón para promocionarse, y la verdad, espero que todos los responsables de esas series hayan cobrado bien, porque si no, tontos de ellos…

Saludos

Búsquedas rápidas en el historial de BASH

Jueves, 6 de Mayo de 2010 Gaspar Fernández Sin comentarios

2683642114_bba3d6383e
Cuando pasamos mucho tiempo en escribiendo en terminal, a veces tenemos la necesidad de repetir algo que escribimos en el pasado. Puede que estemos compilando algún programa, o haciendo un ./configure e instalando dependencias de un programa…
Muchas distribuciones lo tienen por defecto (por ejemplo Gentoo), pero otras muchas (Ubuntu, Mandriva, ArchLinux…) no lo tienen; se trata de activar las teclas de Avance y Retroceso de página para hacer búsquedas en nuestro historial.
Esto sirve, por ejemplo para que, si escribimos algunas letras de una orden que enviamos en el pasado, y pulsemos RePag nos encuentre aquellas órdenes que enviamos en el pasado y nos ahorre unas cuantas pulsaciones de teclado.

Lo que debemos hacer es editar el archivo /etc/inputrc, muchas distribuciones traen ciertas líneas parecidas, por lo que si vemos alguna línea que empiece por “\e[5~” o “\e[6~” deberíamos comentarla (con #) o borrarla; y tras ello introducir lo siguiente:

“\e[5~”: history-search-backward
“\e[6~”: history-search-forward

Para mí, es la forma más cómoda de trabajar.

Foto: Liamdunn (Flickr)

Visita otras webs de la red