How to properly crop and resize for maximum crispness in retina screens. It wasn’t so obvious…

Domingo, 27/Feb/2011 Deja un comentario

Since October 2010 I became an Xcode developer, starting to build apps for all the 3 Apple available display sizes as of today: iPad, iPhone “old” and iPhone “new” (retina). The funny thing is, I had 0 experience at all in the mobile development world.

Ok, once you cope with the nice dpi boost in retina screens (as an user), you need also to take care of things you never thought you had to deal with as a coder.

One of these (I thought) obvious things was creating images and contents for the typical iOS on-screen widgets (buttons, labels, etc…). Some may say, “you don’t need to, Cocoa is pretty enough”. Well, for an uncomplicated application, it might be the case, but if your workteam has a GOOD designer, soon you start to spend some time not only coding, but also using your favorite cropping/editing/trimming/resizing program (typically, gimp, photoshop, etc…) to port his nice and professionally designed interface elements.

When I started trimming images from the shiny designs my coworker created, I somewhat put myself onto “autopilot mode”. That was: You opened the retina master image file (with the full UI on screen), cropped the screen area you wanted, saved it as a @2x version filename, resized the same image file to exactly 50%, then saved it into another file (without the @2x in the filename), and then you took care (just typing it down onto a notebook) of the image dimensions you just created, for a latter usage.

This process shouldn’t be tricky except for quite a common case: Retina buttons you crop from the big UI image, sometimes have odd resolution (here “odd” meaning “not a multiple of 2”).

Imagine you crop a button (in a coarse way), then you refine the crop using some “trim transparent pixels from around the button” tool to just fit the image size to pixels with content (we don’t want to store silly transparent areas surrounding your 24/32 bit png files). Now, look at the new trimmed image size, and type down the resolution you’ve got now (for this article, we’ll suppose our @2x image file measures 157 x 97 pixels).

Then, we might save it to our disk with this filename “some_button@2x.png”. Ok, done.

Now, we need to create the “non-retina” version, for older iPhones, which obviously can only show half the resolution on the same screen area… But wait a moment… The original image resolution wasn’t a multiple of 2, so what does “half” mean in this case? Well, it means “bad news”.
In our case we have to decide which will be our “half resolution”. If the original image was 157 x 97… Half resolution would be 78.5 x 48.5 pixels, but as everyone knows, screen resolutions “don’t have half pixels”, so we have to make an intelligent guess: Do we choose (78 x 48) or (79 x 49)?

Fast answer: Both will give us headaches (in terms of retina display), and I’ll show you why just below.

Anyway, let’s choose the first one and let’s downsize the original retina image (157 x 97) onto a 78 x 48 pixel version. We’ll call it “some_button.png”.

In terms of image quality, when downsizing, we NEVER have to worry (no matter the resolution), because we’re losing resolution no matter what we do. IT’S NOT OUR PROBLEM (today). We should anyway use interpolation, and then our half sized image will be recreated from the bigger resolution one, yielding more than satisfactory results. We would have a problem if we were doing it the other way back: upsizing from low-resolution to high-resolution… But that’s not the case.

OK, right now, we have the 2 necessary versions: “some_button@2x.png” (157 x 97) and “some_button.png” (78 x 48). Now we should import BOTH files inside XCode. Then, when we launch Interface Builder, our new image button appears as a the “named resource” “some_button.png”, ready to be used.
One of the nice things about this process, is that even we imported both PNG files into XCode, we only have to use the “non-retina” filename inside our source files. Why? Because the one dealing with the “which version of the file should I choose” question will be iOS runtime, once our code gets executed on the physical device (iPhone, iPad, iPhone-retina). And even more: all this stuff gets transparently done without our intervention.

In more detail, if iOS detects it’s been run inside a retina iPhone, it automagically chooses to show the @2x version of our image, even in our code we just wrote something like: load my image named “some_button.png” (without the @2x) part.
Ok, once we’ve roughly described how iOS deals with retina images, our problems might start now:

iOS runtime image manager is able to pick high resolution images for being used on the render process, BUT iOS screen resolution, at least “logically” is not 640 x 940 (the new dpi boosted one), but 320 x 480, the “crappy” and old iPhone3 one… That is, in Interface Builder we DESIGN our UI with non-retina resolution, expecting that in runtime, iOS-retina will deal with the pixel doubling process.

And what does it have to do with our image files? Well, here comes the funny part.
I said we were forced to choose among 2 “wrong” resolutions. In our first example, I said: “lets choose the 78 x 48 version”.

If we do that, iOS will build a 78 x 48 container on screen, which will be filled with the 78 x 48 version of our “some_button.png” file. So far so good: our low resolution button gets 100% perfectly shown on screen, no distortion, no nothing. Just crisp pixels (reduced, but crisp).
But if we run the very same code on a retina display, the logical container size will be 78 x 48 (as I said, that is iPhone 3 size), BUT this container will be doubled before rendering anything into it. So our logical 78 x 48 container becomes a physical 156 x 96 container, once it appears onto the retina screen. And now, that’s the point where our @2x file (157 x 97) gets rendered onto the actual screen pixels, inside this 156 x 96 container. And as you might think, yes, this creates UGLY resampling of our image, even the rendering process is only shrinking our image file by just a mere pixel.
One might say: “really? is it SO ugly to the eye?” Without any doubt I say, YES! and I invite you to do the test.
(TO DO: I’ll create a demo webpage to show all this in the near future).

So, first option, downsizing to half size -0.5 pixels was a bad choice. Let’s see what happens if we take the +0.5 pixels version for our “non-retina” file size: 79 x 49 (of course, keeping the retina file size 157 x 97, as it was/is the original resolution our designer created for our button).

If we do ALL the process again, we arrive to the very same conclusion, that is:
-Our non-retina container will now be 79 x 49 pixels.
-Our physical retina container on screen will measure 158 x 98 (doubling the size of the logical container, 79 x 49), and again our big file in disk is still 157 x 97, and then when iOS retina places the image into the container, it will suffer a resample of 1 pixel bigger in both directions: Result? Visual distortion again, and our beautiful and crisp button becomes absurdly blurry.

So, is there a solution for all this? Yes it is (probably more than one), but the one I like most is thinking a bit BEFORE SAVING our first @2x retina image file:
-Instead of just blindly saving it, we should check its canvas size, and we will INCREASE ALL DIMENSIONS (width and/or height) SHOWING odd numbers. In our example, our 157 x 97 file will be upgraded onto a 158 x 98 file, JUST ADDING a row and a column of transparent pixels (on the right and bottom sides of it for example).

Will it visually interfere? Not really, (assuming we’re using PNG-32/24 files), because transparent pixels, as its name say, are transparent.

OK, the second half of my “workaround”, just after having saved the @2x version of our retina button, is halving our new image dimensions to achieve half the resolution with no decimal numbers. In our case we get a 79 x 49 small file. One might say: “hey, that’s the same than the second choice of the wrong examples you showed us”. Well, “yes”, resolution is the same, but built up from a different (1 pixel bigger) master file. If you compare carefully, even resolution is the same, contents won’t.

Are we done yet? Absolutely.

We only need to update our Interface Builder UIButton/UIImageView dimensions container, setting it to 79 x 49.
That’s it? Yes it is. Because whenever iOS retina will render this button on our live application, it will create a (79 x 49) x 2 container size, that is 158 x 98, and now our carefully created @2x image file will EXACTLY match this resolution, rendering a sharp and crisp 1:1 image file with the contents of the @2x some_button.png file we carefully created.

I hope my explanation is kind of understandable, I’m open to corrections and suggestions, so feel free to ask.
I just wanted to write all this personal experience, hoping people will be able to create proper image buttons from day 1, and not from day 100, as it happened to me ūüôā

NOTE: This method I described, is 100% valid also if you want to create “universal mobile web pages”. That means, “with the same .html file you create both normal and high resolution webpages at once”. Safari under iPhone retina will treat ALL measurements as “low resolution”, except for image files. Feed your webpage with “high resolution” images only, and you’re done (your low resolution webpage version will resample bigger resolution images on runtime).
BTW, I’ve made some preliminary tests on my own, and even Android high resolution display devices treat document dimensions as “low-res”, even image files can be “high-res”, so you kill many birds with just one stone.


Post to Del.icio.usShare it on TwitterLike This!

Dropbox, por qué es imprescindible


Windows Live 2009 Messenger: C√≥mo poder volver a hacer click en los enlaces.

Domingo, 26/Dic/2010 3 comentarios

Quien haya estado usando Windows Live 2009 (Vulgarmente “el messenger” o “el MSN”) bajo XP, Vista, 7, etc… se habr√° encontrado con una sorpresa extremadamente desagradable desde mediados de noviembre de 2010:

No se puede hacer click en los enlaces que nos envían nuestros contactos mientras chateamos con ellos, y nos vemos obligados a copiarlos y pegarlos en nuestro navegador manualmente.

Esto en principio, tampoco parece tan complicado. Cuando te pasan 1 enlace, dices “vale”, y copias y pegas. Cuando te pasan el segundo, dices “vale, venga va”, y lo vuelves a hacer. El problema aparece al 4¬ļ, 5¬ļ, o en√©simo enlace que te pasan: uno se aburre y se harta. Y se enfada. Y quiere matar. Y mucho.

Es m√°s, no s√≥lo se harta uno de copiar y pegar, operaci√≥n ya de por s√≠ aburrida, sino que, dentro de MSN todav√≠a sufrimos una vuelta de tuerca m√°s. ¬ŅPor qu√©? porque por alg√ļn motivo desconocido, al arrastrar el raton e intentar seleccionar el texto del enlace, nos vemos envueltos en una aut√©ntica odisea, ya que hace falta seleccionar con bastante precisi√≥n el inicio y el final del enlace en la pantalla. Como no lo hagamos as√≠, en vez de seleccionar, “se nos mover√°” el enlace de sitio, con lo que nos vemos obligados a repetir la operaci√≥n de seleccionar de nuevo.

En cualquier caso, el no poder hacer click, es un problema que est√° ah√≠, que el se√Īor Microsoft se ha sacado de la manga de repente. ¬ŅY por qu√©? Pues porque seg√ļn √©l mismo, “ha aparecido un presunto fallo de seguridad con un gusano que se transmite por MSN, lo estamos estudiando, etc… y blablabla…” Pero que no cunda el p√°nico, no pasa nada chicos, se les ha ocurrido la mejor soluci√≥n: matar moscas a ca√Īonazos capando la posibilidad de hacer click en los enlaces. (facepalm)

Mucha gente cree que detr√°s de esta maniobra, en el fondo lo que el se√Īor microsoft quiere es “estropear el Windows Live 2009” y forzar que la gente se actualice a Windows Live 2011, el cual s√≥lo funciona bajo windows 7. Y la gente, claro, y con todo el derecho, se enfada…

Aun así, sea como sea, si te encuentras con que los links no te funcionan en las ventanas de chat, quieres arreglarlo, y te consideras un poco manitas, la solución para este problema es moderadamente fácil. Así que sigue leyendo.

Primero de todo hay que confirmar que NO TENGAMOS EL MSN ABIERTO. Para ello, en la zona de abajo a la derecha de la barra de tareas, donde aparece el icono MSN con un c√≠rculo de color indicando nuestro estado de conexi√≥n (verde, amarillo, rojo), haremos “bot√≥n derecho” y seleccionaremos “Cerrar”.

Botón Cerrar MSN




Entonces, Y S√ďLO ENTONCES, empezaremos a hacer lo siguiente:

  1. Conseguir un editor hexadecimal (XVI32 sería de lo más fácil que he encontrado por internet, así de entre los gratuitos)
  2. Localizar el fichero ejectuable “del Messenger”. En una instalaci√≥n t√≠pica de Windows XP, est√° en “C:\Archivos de programa\Windows Live\Messenger“, y en esa carpeta, tenemos que localizar el ejectuable, llamado “msnmsgr.exe
  3. Habiendo descomprimido el en nuestra carpeta temporal favorita (C:\temp\ por ejemplo), lo ejecutamos, y una vez dentro, en su barra de men√ļ superior seleccionamos “abrir fichero”.
  4. El fichero que tendremos que abrir es precisamente el que comentamos en el punto 2, as√≠ que exploraremos las carpetas de nuestro PC hasta dar con el tal “msnmsgr.exe
  5. Una vez lo hayamos abierto, en pantalla nos saldr√°n una serie de s√≠mbolos raros que no nos tienen que asustar. De momento, lo que haremos, ser√° “buscar una palabra” dentro de tanto galimat√≠as.
  6. Dentro de XVI32 todav√≠a, y con el icono “lupa” (buscar), nos saldr√° una opci√≥n para precisamente eso, buscar. Si nos damos cuenta, dice “buscar cadena de texto” o “buscar cadena binaria”. Lo que tenemos que hacer es seleccionar la opci√≥n “buscar una cadena de texto”. Pero cu√°l concretamente? √Čsta: ¬† ¬† ¬†hotlinks
  7. Una vez hemos encontrado la palabra hotlinks dentro del ejecutable, simplemente tenemos que cambiarla por otra, la que sea, y que ocupe lo mismo… Para no complicarnos mucho, lo que yo he hecho es cambiar simplemente la ‘h‘ inicial por otra letra, por ejemplo, la ‘s‘.
  8. Una vez hemos hecho esto, ya está todo. Salimos del programa XVI32, (nos dirá si queremos guardar en disco la nueva versión del fichero msnmsgr.exe) y le diremos que sí.
  9. Sólo nos queda volver a lanzar el MSN, así que desde el explorador de ficheros, hacemos doble click en el fichero msnmsgr.exe y voi-là. A partir de ahora,  si un contacto nos envía un enlace con una página de internet en la ventana del chat, volveremos a poder hacer click con total confort y comodidad.

DISCLAIMER: SI TODA ESTA EXPLICACI√ďN TE PARECE DEMASIADO COMPLICADA O T√ČCNICA, PIDE AYUDA A UN AMIGO QUE SEPA ALGO M√ĀS QUE T√ö. Si se siguen estos pasos de manera escrupulosa, tiene que funcionar, con lo que si no funciona, algo has hecho mal. Declino toda responsabilidad en caso de que tu copia de Windows Live 2009, (“el messenger”, vamos) deje de funcionar. En el peor de los casos, desinstal√°ndolo y volvi√©ndolo a instalar, tendr√≠a que volver a funcionar.
Nota:Toda esta información es una adaptación en castellano de un artículo en inglés aparecido aquí


Dropbox, por qué es imprescindible

Post to Del.icio.usCompártelo en TwitterMenéalo!!Like This!