ios - tamaño - miniatura personalizada video facebook
¿Cómo se puede cargar rápidamente una versión de menor resolución de una imagen para una miniatura? O simplemente, ¿cómo es mejor crear una imagen en miniatura? (9)
1 solución que algunos de los usos de la aplicación tienen 2 versiones de la imagen 1 es de alta resolución la segunda es de baja resolución. Miniatura descargada inicialmente cuando el usuario hace clic en la imagen en miniatura extiende la imagen de baja resolución al tamaño grande y comienza a descargar la alta imagen de resolución en el fondo ... tan pronto como se completa la descarga de la imagen de alta resolución, la miniatura de menor resolución es reemplazada por la imagen de alta resolución en la vista de la imagen.
Otra solución es descargar miniaturas primero y en segundo plano comenzar la descarga de las imágenes de alta resolución para que la mayor parte del tiempo cuando el usuario hace clic en una miniatura probablemente obtenga una imagen almacenada de alta resolución de la memoria.
Muchas aplicaciones como Tweetbot muestran miniaturas en sus controladores de vista de tabla para una imagen de resolución mucho más alta.
Por ejemplo, esta imagen muestra una miniatura que, al tocarla, revela una imagen más grande:
Sin embargo, estoy muy confundido sobre cómo se cargan estas imágenes. Mi pensamiento sería que la imagen original se carga y luego se reduce al tamaño de miniatura y se muestra. Sin embargo, me resulta difícil de creer, ya que la imagen tarda una buena cantidad de tiempo en cargarse / descargarse a resolución completa, por lo que al hacer que cada imagen se encoja, parecería que llevaría bastante tiempo. Pero estos parecen cargarse muy rápido.
También soy escéptico, dado que cuando tocas la imagen, tarda un segundo en cargarse antes de que se muestre la imagen de resolución completa, lo que me lleva a pensar que si descargaron la resolución completa solo se almacenaría en caché temporalmente y se cargaría instantáneamente cuando el usuario lo toca.
Así que tengo curiosidad de cómo exactamente uno lograría un sistema de miniaturas similar al de esta aplicación. Dado un enlace a una imagen, como la que se muestra en la imagen de arriba, ¿cómo tomaría rápidamente la imagen en la URL y la presentaría como una miniatura ?
Es probable que sea diferente para cada aplicación.
En el caso de Tweetbot, es casi seguro que obtienen la miniatura de los servidores de Twitter y obtienen la resolución completa solo cuando tocan la miniatura. Entonces, en este sentido, es solo una URL diferente y Twitter está haciendo la miniatura.
Las aplicaciones también pueden hacerlo localmente. La aplicación Fotos de Apple y Camera Roll crean miniaturas tan pronto como tomas una foto y las guardas localmente para mostrarlas en la vista de colección para preservar la memoria. Es solo cuando lo toca que carga la imagen de resolución completa de la memoria. Incluso hay evidencia y precedentes de que ni siquiera cargan la imagen de resolución completa inmediatamente solo cargando una imagen necesaria para el tamaño de la pantalla hasta que pellizca para acercarla y luego la intercambia por otra imagen.
Básicamente, hay muchas técnicas simples que mostrará Google rápidamente para hacer una miniatura de una imagen en el código. Pero el método de cada aplicación será específico para su flujo de usuario único.
Lo más probable es que sean imágenes separadas (las miniaturas) que se crearon cambiando el tamaño de la imagen original de resolución completa y luego se guardaron por separado de la imagen de resolución completa, razón por la cual las miniaturas parecen cargarse muy rápido. He escrito una aplicación que hace algo similar (aunque guarda localmente tanto la imagen en miniatura como la resolución completa). Este es el código -
-(void)setThumbnailDataFromImage:(UIImage *)image//image is full res image that you want a thumbnail of
{
CGSize origImageSize = [image size];
CGRect newRect = CGRectMake(0, 0, 50, 50);
float ratio = MAX(newRect.size.width/origImageSize.width, newRect.size.height/origImageSize.height);
UIGraphicsBeginImageContextWithOptions(newRect.size, NO, 0.0);
//the following two lines round the edges of the thumbnail
UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:newRect cornerRadius:5.0];
[path addClip];
CGRect projectRect;
projectRect.size.width = ratio * origImageSize.width;
projectRect.size.height = ratio * origImageSize.height;
projectRect.origin.x =(newRect.size.width - projectRect.size.width)/2.0;
projectRect.origin.y =(newRect.size.height-projectRect.size.height)/2.0;
[image drawInRect:projectRect];
UIImage *smallImage = UIGraphicsGetImageFromCurrentImageContext();
if (thumbnailDataArray==nil) {
thumbnailDataArray = [[NSMutableArray alloc]init];
}
NSData *data = UIImagePNGRepresentation(smallImage);
if (thumbnail == nil) {
[self setThumbnail:smallImage];
[self setThumbnailData:data];
}
NSData *otherObject = UIImagePNGRepresentation(smallImage);
[thumbnailDataArray addObject:otherObject];
UIGraphicsEndImageContext();
}
luego para cargar la miniatura
-(UIImage *)thumbnail
{
if (!thumbnailData) {
return nil;
}
if (!thumbnail) {
thumbnail = [UIImage imageWithData:thumbnailData];
}
return thumbnail;
}
luego, cuando se toca la miniatura, se carga la imagen completa de res
Por lo general, hay 2 imágenes creadas por el servidor y no el cliente, y el servidor proporciona 2 URL para recuperar las imágenes, una para imágenes en miniatura y otra para la imagen completa (esto es lo que sucede en el 90% de las aplicaciones) , por lo que se UIImageView
su UIImageView
((o quien sea el responsable) cargue la miniatura, luego cargue la imagen de resolución completa y la guarde en la memoria caché, de modo que cuando haga clic en ella se abra rápidamente. Ahora hay muchos casos:
- El servidor está realmente rápido, y estás conectado a un wifi rápido, por lo que la aplicación puede cargar la imagen rápidamente.
- El tamaño de la imagen no es realmente grande, por lo que cargar la imagen de resolución completa no lleva tiempo, de todos modos, se muestra en un teléfono con el tiempo.
Si quiere lograr lo que mencionó, esta biblioteca puede ayudarlo mucho.
Así que tengo curiosidad de cómo exactamente uno lograría un sistema de miniaturas similar al de esta aplicación. Dado un enlace a una imagen, como la que se muestra en la imagen de arriba, ¿cómo tomaría rápidamente la imagen en la URL y la presentaría como una miniatura?
Sugeriría usar FilePicker
en su aplicación.
https://www.inkfilepicker.com/
Digamos, por ejemplo, que la imagen de tamaño completo se almacena en
https://www.filepicker.io/api/file/JhJKMtnRDW9uLYcnkRKW
Puede llamar a una versión recortada usando la URL
https://www.filepicker.io/api/file/JhJKMtnRDW9uLYcnkRKW/convert?crop=100,135,220,220
Entonces, simplemente construye esta URL dinámicamente en el código para adaptarse a lo que necesite.
Aquí hay un ejemplo de esto con miniaturas del sitio de Filepicker. Enlace aquí: https://www.inkfilepicker.com/products/javascript_v1/
Lógicamente, debe tener una versión de baja resolución en el servidor y puede descargarla para crear una miniatura usando el siguiente código. La mejor opción es tener miniaturas en el servidor.
Puede usar el siguiente código para crear una miniatura con ajuste de aspecto.
-(UIImage*)scaleImage:(UIImage *)orgImage toSize:(CGSize)size
{
UIGraphicsBeginImageContext(size);
[orgImage drawInRect:CGRectMake(0, 0, size.width, size.height)];
UIImage* scaledImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return scaledImage;
}
- (UIImage *)fitImage:(UIImage *)orgImage toSize:(CGSize)size
{
CGSize imageSize = orgImage.size;
float widthRatio = (size.width/imageSize.width);
float heightRatio = (size.height/imageSize.height);
float factor = widthRatio < heightRatio ? widthRatio : heightRatio;
if (factor > 1.0) {
factor = 1.0;
}
CGSize newSize = CGSizeMake(imageSize.width * factor,
imageSize.height * factor);
UIImage *img = [self scaleImage:orgImage toSize:newSize];
return img;
}
Llame a fitImage: con el tamaño de miniatura que desea generar.
Si tiene que hacer la reducción en el dispositivo (es decir, el servidor no proporciona una versión más pequeña), probablemente desee evitar cargar e inflar primero la imagen de tamaño completo en la memoria. (La mayoría de las otras respuestas están sugiriendo esto en este momento).
En su lugar, puede usar el método CGImageSourceCreateThumbnailAtIndex
para crear una miniatura directamente desde los datos originales (comprimidos) sin expandirla primero (envolviéndolo en un CGImageSource). Puede ver un ejemplo completo de esto en la Guía de programación de E / S de imágenes de Apple en Creación de una imagen en miniatura a partir de un origen de imagen .
Para imágenes de origen más bien pequeñas, esto probablemente no tenga un gran impacto, pero para una más grande puede ayudar mucho, especialmente con el consumo de memoria.
Por lo tanto, puede crear fácilmente una versión más pequeña de la imagen grande y almacenarla en caché. Hay varias formas de hacer esto. Tenga en cuenta que CGContextDrawImage(CGContextRef c, CGRect rect, CGImageRef image)
se escalará según corresponda. No desea hacer esta escala en vivo cada vez que sea más probable, por lo que querrá dibujar en un CGBitmapContext
y luego almacenarlo en caché.
En ese sentido, es posible que Path haya realizado la mayor parte del trabajo pesado en la biblioteca que lanzaron recientemente: https://github.com/path/FastImageCache
Parece tener potencial a partir de la documentación (aunque aún no he investigado el código). Parece que llamará a su bloque para dibujar la imagen en su caché. Así que un simple sorteo en el tamaño que indican lo reducirá y lo guardará en el caché.
Usa FastImageCache.
https://github.com/path/FastImageCache
Es woo-hoo! rápido.
(Al mostrar las miniaturas una vez almacenadas en caché para un desplazamiento suave y sedoso, tened cuidado. No es especialmente mágico que la miniatura inicial se visualice más rápido. Tener vistas previas de baja resolución guardadas en algún lugar, como han señalado otras personas, es tu única ayuda allí).