2009-11-10 18 views
12

Básicamente estoy descargando imágenes de un servidor web y luego guardándolas en caché en el disco, pero antes de hacerlo quiero enmascararlas. estoy usando el código de enmascaramiento todo el mundo parece apuntar a la que se puede encontrar aquí: http://iosdevelopertips.com/cocoa/how-to-mask-an-image.htmlEscribiendo una imagen enmascarada en un disco como archivo PNG

¿Qué sucede, sin embargo, es que la imagen muestra bien, pero la versión que se escribe en el disco con

UIImage *img = [self maskImage:[UIImage imageWithData:data] withMask:self.imageMask]; 
[UIImagePNGRepresentation(img) writeToFile:cachePath atomically:NO]; 

tiene su canal alfa invertido en comparación con el que se muestra más adelante (utilizando la misma instancia de UIImage aquí).

¿Alguna idea? Necesito enmascarar la versión almacenada en caché, de lo contrario, mostrar las imágenes en una vista de tabla es terriblemente lento si tengo que enmascararlas todo el tiempo.

Edit: Así que sí, UIImagePNGRepresentation (img) parece invertir el canal alfa, no tiene nada que ver con el código que escribe en el disco, lo cual es bastante obvio, pero lo comprobé de todos modos.

+0

¿Obtiene el mismo resultado si usa UIImageJPEGRepresentation? No sugiero que cambies a JPEG. Me pregunto si tiene el mismo efecto. –

+0

Lo intentaré, aunque JPEG derrota el propósito de tener una máscara alfa. –

+0

Por extraño que parezca, el JPEG se ve bien, la máscara se ha aplicado correctamente. –

Respuesta

5

Véase la descripción en CGImageCreateWithMask en CGImage Reference:

La imagen resultante depende de si el parámetro de máscara es una máscara de imagen o una imagen. Si el parámetro de máscara es una máscara de imagen, las muestras de fuente de la máscara de imagen actúan como un valor alfa inverso. Es decir, si el valor de una muestra fuente en la máscara de imagen es S, entonces la región correspondiente en la imagen se mezcla con el destino usando un valor alfa de (1-S). Por ejemplo, si S es 1, entonces la región no está pintada, mientras que si S es 0, la región está completamente pintada.

Si el parámetro de máscara es una imagen, entonces sirve como una máscara alfa para mezclar la imagen en el destino. Las muestras fuente de la máscara 'actúan como un valor alfa. Si el valor de la muestra fuente en la máscara es S, entonces la región correspondiente en la imagen se mezcla con el destino con un alfa de S. Por ejemplo, si S es 0, entonces la región no está pintada, mientras que si S es 1, la región está completamente pintada.

Parece que por alguna razón la máscara de imagen se trata como mask image para enmascarar mientras se guarda. De acuerdo con:

para guardar correctamente con UIImagePNGRepresentation, hay varias opciones:

  1. Uso versión inversa de la máscara de imagen.
  2. Use "máscara de imagen" en lugar de "máscara de imagen".
  3. Renderice a un contexto de mapa de bits y guárdelo, como se menciona en epatel.
0

¿Usted ha visto este post? No estoy seguro de si es relevante, pero parece ser similar

Any idea why this image masking code does not work?

+0

No parece estar relacionado ya que conozco las peculiaridades de crear una máscara, he probado con varios formatos diferentes para la máscara, etc. Además, mi máscara se aplica bien cuando se muestra, solo cuando guardo la imagen ya enmascarada para el disco se invierte el canal alfa –

14

¿Qué hay de dibujo en una nueva imagen, y luego guardar eso?

UIGraphicsBeginImageContext(img.size); 
[img drawAtPoint:CGPointZero]; 
UIImage *newImg = UIGraphicsGetImageFromCurrentImageContext(); 
UIGraphicsEndImageContext(); 
[UIImagePNGRepresentation(newImg) writeToFile:cachePath atomically:NO]; 

(no probado)

+0

Sí, eso funciona. Sin embargo, no es ideal, ya que de acuerdo con mis medidas (muy toscas), lleva más tiempo volver a dibujar la imagen como en el código anterior (menos el '-writeToFile: atómicamente') que dibujar la imagen desde cero utilizando los comandos Core Graphics. ¿Tiene más información sobre por qué funciona su sugerencia y si existe una forma más eficiente de hacer lo mismo? – Stuart

+0

Supongo que la máscara es una "cosa" separada de la imagen. Algo que UIKit/Quartz puede manejar y dibujar, pero cuando quiere guardarlo como una imagen con máscara como un canal alfa, la imagen debe componerse con la máscara para obtener su "mapa de bits" final antes de guardarla. – epatel

+0

@epatel Te amo, amigo. He estado sacando mi cabello. Estoy tratando de enmascarar y guardar en el archivo (caché) antes de que cualquiera de mis lecturas de código normales del archivo (de esa manera enmascare una vez, no cada vez que se muestra la vista), y tu código era necesario después de mi "UIImage * maskedIcon = [UIImage imageWithCGImage: maskedImageRef]; " para hacer que funcione ¡Gracias! –

Cuestiones relacionadas