Salvar JPG con mucho menos peso sin perder calidad

Iniciado por Fran1946, 8 Mayo 2015, 19:37 PM

0 Miembros y 3 Visitantes están viendo este tema.

Fran1946

Lo he visto por encima, y efectivamente es un código muy complicado, pero siempre es bueno tener códigos como este para poder utilizarlo en una aplicación, sin tener que utilizar OCX para exportar a JPG.
Lo voy a mirar con mas detalle a ver si me vale para salvar un PictureBox de una aplicación que tengo, que grafica varios planos mecánicos por código.

Pero lo he ejecutado cargando un BMP y salvado a JPG con calidad 100% y 1:1, y luego el mismo BMP cargado con Paint de XP, y salvado a JPG y tiene 60% menos de peso que el salvado con este código.
Me gustaría saber que algoritmo de compresión JPG tiene Paint, que salva los JPG con el peso mas bajo posible, me parece increíble, por que el formato JPG no lo desarrolló Microsoft, y no entiendo como mejora la compresión en un porcentaje enorme respecto al original. 

Fran1946

#11
Hola a todos:

Ya termine la aplicación, y funciona muy bien, gracias a la ayuda de okik y a la de otro usuario de otro foro.

Para quien quiera ver como funciona, este es el link del vídeo que he hecho:

https://www.youtube.com/watch?v=kr35DvIztYU

Solo me queda una pregunta para okik:

Si has visto el vídeo, veras que después de haber salvado los archivos, tiene una opción de ver y comparar el original y el convertido en el visor de imágenes y fax de windows.
Pues yo quería que al visualizar las imágenes en el visor de Win, a continuación del nombre del archivo, se viera ' - Original' o ' - Convertido', en lugar de:
- Visor de imágenes y fax de Windows
Y esto ya lo tenía conseguido y cambiaba el Caption del visor de Win poniendo una interrupción después de la linea del código que manda el mensaje, pero si quito la interrupción, lo manda y se ve un instante, pero a continuación vuelve a verse ' - Visor de imágenes y fax de Windows'  

No se si esto se puede evitar, y conseguir que se vea, por ejemplo
En lugar de:
Imagen 1 - Visor de imágenes y fax de Windows
Se vea:    
'Imagen 1 - Convertido', o 'Imagen 1 - Original'

Gracias y un saludo.




okik

#12
Buen trabajo  ;-). Felicidades por le programa y la idea.

En cuanto a lo de cambiar el nombre yo siempre he usado la función API  SetWindowText.

Código (vb) [Seleccionar]
Private Declare Function SetWindowText Lib "user32" Alias "SetWindowTextA" (ByVal hwnd As Long, ByVal lpString As String) As Long

Tan sólo necesitas obtener el Handle de la ventana, en este caso del visor de imágenes de Windows. El Handle, como ya sabes puedes obtenerlo con FindWindow y necesitas el nombre de clase de la ventana que es "Photo_Lightweight_Viewer" y "ShlmgVw:CPreviewWnd" en XP, o bien el mismo título de la ventana.

Luego el código podría ser:

Código (vb) [Seleccionar]
Dim hwndViewer As Long
Do While hwndViewer = 0
hwndViewer = FindWindow("Photo_Lightweight_Viewer", vbNullString)
DoEvents
Loop
Call SetWindowText(hwndViewer, "Imagen 1 - Convertido")


*Recuerdo que si se sustituye "vbNullString" por el título de la ventana sólo se obtendrá el handle de una ventana que contenga dicho título.

Saludos

Fran1946

Gracias okik:

Código (vb) [Seleccionar]
Private Declare Function SetWindowText Lib "user32" Alias "SetWindowTextA" (ByVal hwnd As Long, ByVal lpString As String) As Long

Si así lo he echo yo con 'SetWindowTextA'

Tan sólo necesitas obtener el Handle de la ventana, en este caso del visor de imágenes de Windows. El Handle, como ya sabes puedes obtenerlo con
FindWindow y necesitas el nombre de clase de la ventana que es "Photo_Lightweight_Viewer" y "ShlmgVw:CPreviewWnd" en XP, o bien el mismo título de la ventana.

Luego el código podría ser:

Código (vb) [Seleccionar]
Dim hwndViewer As Long
Do While hwndViewer = 0
hwndViewer = FindWindow("Photo_Lightweight_Viewer", vbNullString)
DoEvents
Loop
Call SetWindowText(hwndViewer, "Imagen 1 - Convertido")


Esto no funciona, no obtiene el handle, siempre  = 0, ya te dije que esta función falla mucho.

Pero yo si consigo el handle siempre, con un módulo de clase que tengo se llama 'clsEnum.cls'

Y me funciona y cambia el captión, como he comentado, pero solo desde VB6, poniendo una interrupción, pero si la quito, entonces la cambia un instante y vuelva a ponerse:  ' - Visor de imágenes y fax de Windows' 

Subo 2 capturas para que lo veas:


imagen


subir fotos a internet

Un saludo.

pkj

#14
Veo 2 problemas:
1, si el visor vuelve a cambiar el titulo debe ser que tiene alguna especie de timer que lo actualiza, porque con otros programas parece ser un cambio mas permanente.
2, tu tienes asociado el visor de imagenes de windows a las fotos, pero mucha gente asocia un visor diferente y tu programa no les va a servir. A mi de hecho me aparece el visor de windows como "visualizador de fotos de windows", pero ademas las imagenes las tengo asociadas a ACDSee.

La solucion mas simple es que, justo despues de guardar la imagen con sdpaint la renombres. Asi el propio visor te muestra si es procesada o no.
Hacer un "Guardar como..." no te interesa porque tendrias que ir dandole nombres durante todo el proceso, pero justo despues del sendmessage con ctrl+G puedes poner algo como:
Código (vb) [Seleccionar]

Name ListFiles.List(i) As Left(ListFiles.List(i), Len(ListFiles.List(i)) - 4) & "_Procesado.jpg"


como luego borras la lista no hace falta, pero si no la borras puedes actualizar el nuevo nombre:
Código (vb) [Seleccionar]

ListFiles.List(i) = Left(ListFiles.List(i), Len(ListFiles.List(i)) - 4) & "_Procesado.jpg"


Tambien puedes guardar las originales con el "_Original" al final al copiarlas o renombrandolas despues.
Incluso te puede interesar hacer esto ultimo mejor que otra cosa, ya que solo renombras las originales, y las nuevas que son las que se supone que te interesan mantienen su nombre original.

Que se de bien.

Fran1946

Hola okik:

Buena sugerencia, esto ya lo había pensado para otros, no para mí que ya lo he comprobado con mas de 2000 fotos pasando de 2.34 Gb a 1.4 Gb

de espacio, ya que después de comprobar que son iguales lo normal es borrar la carpeta 'BackPaint' donde están lo originales, por que el

programa si no puede salvar 'convertir' un archivo lo deja como original, y lo apunta en el archivo 'Informe convertidos.txt' como  0.0% menos.

Esto es el contenido de ''Informe convertidos.txt' de la conversión se solo 2 fotos:

Fecha: 18/05/2015    Hora: 19:00:16

1 - T:\DATOS\Camara\Cumple Susi y Germán 2015\_MG_2237.JPG -  (Antes) 5597,5 Kb / (Despues) 822,5 Kb - 85,3 % menos
2 - T:\DATOS\Camara\Cumple Susi y Germán 2015\_MG_2239.JPG -  (Antes) 9107,1 Kb / (Despues) 1475,4 Kb - 83,8 % menos

2 Archivos originales copiados en: T:\DATOS\Camara\Cumple Susi y Germán 2015\BackPaint\, Total: 14.704,6 Kb

-------------------------------------------------------------------------------------------------

2 Archivos convertidos en: T:\DATOS\Camara\Cumple Susi y Germán 2015\, Total: 2.297,9 Kb
Total: 12.406,7 Kb menos, promedio de ahorro total: 84,4 % menos
-------------------------------------------------------------------------------------------------
Pero lo ideal sería poder cargar el original y el convertido, sin cambiar el Caption del visor, ya que el programa indica cual estas viendo, pero de la forma como carga los archivos de 'SDPaint' en el mismo visor, no abriendo otro nuevo, por que de esta forma no hay un parpadeo entre una imagen y la otra como ocurre ahora, y eso destruye el poder ver la misma imagen antes y después, sin parpadeo, o sea como se ve si hubiera en la misma carpeta, por ejemplo, 2 imágenes:
Imagen_1 e Imagen_1A, y selecciones en el explorer las 2 y con botón derecho en una de ellas eliges en el menú emergente 'Vista previa' y entonces con cualquier tecla de flecha del teclado, pasas de una otra sin parpadeo y entonces si ves claramente que no distingues cual es cual.
Y eso no se si se puede conseguir utilizando el código del usuario del otro foro, por que he probado teniendo una imagen cargada en el visor de Win y arrastro otra desde el Explorer, y la carga pero con parpadeo.

Dime si conoces algún visor gratuito, muy simple, para poder probar con el código que utilizo con 'SDPaint'.

Gracias de nuevo por tu interés.

Si quieres, tu u otras personas, descarga el programa aquí, y lo pruebas:

https://dl.dropboxusercontent.com/u/51073224/FOTOS%20JPG.rar

Un saludo.


pkj

Puedes intentar crear tu propio visor dentro del proyecto.
Asi cargas las imagenes p.ej en 2 picturebox diferenes y despues ocultas o muestras el que quieres, con los mensajes y descripciones que quieras.
No creo que sea muy complicado si no tienes que manipular la imagen.

Saludos

Fran1946

Gracias pkj:

Si es buena idea, había hecho un visor con 2 PictureBox, uno al lado del otro, y que el de la izquierda, al mover la imagen con el mouse, el otro movía la suya de la misma forma, pero el movimiento es lento.

Pero voy a probar tu idea, pero con imágenes muy grandes como las de mi cámara de 5184x3456, no se ve entera en un monitor de 20-22", con autosize=true, y si no la imagen solo ves una parte superior arriba.

Pero voy a probar con un control Image, con Stretch=true, a ver si la carga es rápida.

Un saludo.

Fran1946

Bueno, pues ya está terminado el programa, funciona muy bien.

Si queréis ver la última versión con visor propio, y funciones que facilitan poder comparar los originales con los convertidos, de forma muy cómoda y fácil.

Este es el link del vídeo nuevo:

https://www.youtube.com/watch?v=BkmX5sx_bGw

Y este es el link de descarga del programa, para quien lo necesite, solo hay que descomprimir el rar en C;\, no tiene instalación:

https://dl.dropboxusercontent.com/u/51073224/FOTOS%20JPG.rar

Un saludo, y gracias a todos por vuestra ayuda.


pkj

Felicidades  ;-)
Parece que al final has logrado tu objetivo.