jueves, 18 de enero de 2018

Crear clases java JPA de SQL SERVER.

1. Introducción

Tengo una BD antigua SQL Server 2000 y quiero generar algunas clases JPA para acceder a consulta etc.

Existe en Eclipse una ultilidad llamad JPATools. Se puede ejecutar si tu proyecto tiene la FACET de JPA.

Pero NO va bien en SQL Server versiones antiguas ya que no puede ver el SCHEMA "dbo" que es el esquema por omisión cuando no se crean eschemas. Busca un Catalog y como no hay ninguno creado no muestra nada

Para ello recurrimos a NETBEANS.

2. Proceso

1. Descargar un jar antiguo que pueda manejar esta información como sqljdbc-1.2.0.jar desde Java2s , también se puede utilizar el jtds . Vamos a utilizar ahora jtds.


2. En la pestaña de services arriba a la izquierda (si no está se debe incorporar mediante el menú superior Windows, en DataBases , boton derecho New Connection

Y seleccionamos justo lo que hay en pantalla



3. crear la conexion a SQL Server seleccionando url del servidor, puerto 1433, usuario, contraseña, base de datos y schema "dbo". Probar la conexión con Test Connection y verificar que no hay problemas.



3. Crear un proyecto java, crear un package y en boton derecho sobre el package hacer New Entity From Database, se busca la conexión creada anteriormente , y se seleccionan las tablas. Y voila!!!



Ojo hay que tener creadas primary key!!

=======================================================================
ANEXO (Crear la conexión (TOTALMENTE INUTIL)


1. SQL Server 2000


a. Descargar el fichero sqljdbc-1.2.0.jar desde Java2s



b. Crear una nueva connexion tipo SQL Sever


c. Indicar other driver y buscar el jar en la carpeta de descarga. Se busca el driver desde el primer símbolo que hay des. Ojo estas propiedades de URL etc se definen en el paso d.






Indicar estas propiedades




3. Posibles problemas

Si por algún motivo, en vez de crear restricciones "primary key" en una tabla se ha creado "unique" o "unique index", hay que crear la restricción "primary key" sinó, Netbeans se opnone a crear las clases JPA de dicha tabla, para ello se puede crear. Veamos como de golpe las creamos en 9 tablas, y solucionamos el problema

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
ALTER TABLE RRRR01 ADD CONSTRAINT RRRR01_pk PRIMARY KEY (rr01nume);
ALTER TABLE RRRR02 ADD CONSTRAINT RRRR02_pk PRIMARY KEY (rr02nume);
ALTER TABLE RRRR03 ADD CONSTRAINT RRRR03_pk PRIMARY KEY (rr03nume);
ALTER TABLE RRRR04 ADD CONSTRAINT RRRR04_pk PRIMARY KEY (rr04nume);
ALTER TABLE RRRR05 ADD CONSTRAINT RRRR05_pk PRIMARY KEY (rr05nume);

ALTER TABLE RRRR06 ADD CONSTRAINT RRRR06_pk PRIMARY KEY (rr06nume);
ALTER TABLE RRRR98 ADD CONSTRAINT RRRR98_pk PRIMARY KEY (rr98nume);
ALTER TABLE RRRR99 ADD CONSTRAINT RRRR99_pk PRIMARY KEY (rr99nume);
ALTER TABLE RRRR00 ADD CONSTRAINT RRRR00_pk PRIMARY KEY (rr00nume);


lunes, 15 de enero de 2018

Informática Jurasica (II). Ejecutar comandos MSDOS desde VB6

Saludos,

He tenido muchos problemas con mis antiguas aplicaciones VB6. Uno de los mayores problemas era ejecutar una aplicacion o fichero de comandos ".bat".

Parece ser tal y como  dice C0ding que hay que dar estos pasos:

1. En referencias del proyecto VB6.0 hay que marcar "Microsoft Script Host Object Model"
2. Crear un fichero con extensión ".bat" por ejemplo "provaVB60.bat" en "E:\CONF\KK\" como por ejemplo:


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
@echo off 
title Hacer media de dos numeros 
echo "El primer parametro es " %1
echo "El segundo parametro es " %2
set/p num1=Cual es el primer numero? 
set/p num2=Cual es el segundo numero? 
set/a media= (%num1% + %num2%) / 2 
echo. 
echo La media es %media% 
java -version
pause >nul 
exit 

Aquí evaluamos si hay 2 parámetros de entrada, pedimos 2 números, sacamos media y tabién probamos a ejecutar java para ver que versión tenemos instalada. Pues parece ser que funciona.

3. Creamos una pantalla y con un boton y el código VB de la pantalla es:


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
Dim wshThisShell As WshShell
Dim lngRet As Long
Dim strShellCommand As String
Dim strBatchPath As String

Sub EjecutarComando()
  Set wshThisShell = New WshShell
  strBatchPath = "E:\CONF\KK\provaVB6.bat" & """" & " hola guapo" & """"
  strShellCommand = """" & strBatchPath & """"
  lngRet = wshThisShell.Run(strShellCommand, vbNormalFocus, vbTrue)
End Sub

Private Sub Command1_Click()
  Call EjecutarComando
End Sub

En la línea 8 aparece como se llama con parámetros, en este caso hemo colocado también 2 parámetros. Observar que los parámatros se han colocada entre comillas dobles y que el espacio en  blanco es la separación entre parámetros. En este caso detecta 2 parámetros hola y guapo.




lunes, 8 de enero de 2018

Crontab en Ubuntu

Ahora que ya sabemos:

  • crear un jar en Maven
  • localizar recursos dentro de la carpeta donde se encuentra el jar
Podemos realizar un crontab en Ubuntu para que se pueda ejecutar un proceso cada cierto tiempo.


1. Ver los procesos que tenemos programados

crontab -l

Se puede ejecutar como sudo para ver si el administrador ha programado algo. Se ejecuta desde la consola.

2. Editar / crear procesos


crontab -e

Con ello nos pide un editor por omisión, que será mejor utilizar el nano.

Pero con el nano podemos tener algún problemilla si lo utilizamos poco. Por tanto es conveniente copiar le contenido que nos muestra la consola y ejecutamos gedit que es mas fácil y cuando hayamos terminado, copiamos a nano lo que hemos hecho. Con Mayúscula Control o guardamos. Si no queremos guardar Mayúscula Control x.

3. Formato del fichero

Normalmente hay 5 campos para definir fecha y hora (separados por un espacio en blanco) junto con el comando a ejecutar. en concreto los cinco campos de tiempo son:
  • minuto
  • hora
  • día del mes
  • mes
  • dia de la semana
Si hay algún campo que no nos sirve se coloca un asterisco "*".

Se puede colocar un signo menos para indicar un intervalo. Por ejemplo "1-5" en primer campo indica que se repite el comando cada minuto pero solo entre en primer y quito minuto. Si ese mismo valor lo colocamos en día de la semana indica que se ejecutaría de lunes a viernes.

En nuestro caso concreto queremos ejecutar un jar cuya ubicación absoluta es: /home/ximo/misjars/jar01.jar 

Pero queremos ejecutarlo con java 9 y nosotros tenemos por omisión java 8. Para ello tenemos que darle la ruta absoluta del ejecutable de java 9 que en mi caso es:

/usr/lib/jvm/java-9-oracle/bin/java

Si queremos ejecutar el jar de lunes a viernes todas las horas desde las 8 hasta las 16 horas quedaría:



00 08-16 * * 1-5 /usr/lib/jvm/java-9-oracle/bin/java -jar /home/ximo/misjars/jar01.jar


Si queremos ejecutar el jar cada 10 minutos de lunes a viernes todas las horas desde las 8 hasta las 16 horas quedaría: (ver The Geek Stuff).


*/10
00 08-16 * * 1-5 /usr/lib/jvm/java-9-oracle/bin/java -jar /home/ximo/misjars/jar01.jar

Java: Localizar la carpeta que incluye a un proyecto java o a un jar

Lo que voy a decir es un pequeño resumen de lo que se ha comentado en StackOverflow.


Primeramente veamos algunas de las posibilidades manejadas:

1. System.getProperty("user.dir")

En este caso nos indica el directorio donde estamos ahora. Poe ejemplo si estamos en /home/ximo y ejecutamos en la consola : java -jar ./misAplicaciones/aplicacion01.jar , el resultado será /home/ximo y no donde está la aplicación. Por tanto puede ser problemático.


2.  System.getProperty("java.class.path")

Aquí nos indica cada una de las rutas para localizar los jars utilizados. Por tanto a bote pronto, creo que no nos puede servir mucho.

3. La mayor parte de las opciones parten de localizar una clase, y a partir de esta localización ya se busca lo que se quiere. Para obtener la clase desde un método no estático basta con:

    this.getClass()

Pero si estamos en un método estático , las soluciones aportadas en StackOverflow son:


  • MyClass.class(): Permite refactorización, es la más rápida pero no funciona con copia y pega entre 2 clases.
  • MethodHandles.lookup().lookupClass(): Desde Java 7. Parece ser la mejor alternativa, ya que aunque no es tan rápida como la anterior, si permite copia y pega. A continuación ser detallan otras alternativas (para obtener el nombre de la clases) pero su rendimiento puede dar mucho que desear:
  • new Object() { }.getClass().getEnclosingClass().getName();
  • Thread.currentThread().getStackTrace()[1].getClassName();
  • System.getSecurityManager().getClassContext()[0].getName();


4. Si estamos en un jar, se puede obtener la carpeta que contiene el jar, a partir de nuestra clase de esta forma:

   CodeSource codeSource = aClass.getProtectionDomain().getCodeSource();
    File jarFile;
    jarFile = new File(codeSource.getLocation().toURI());
    String s=jarFile.getParentFile().getAbsolutePath();

5. Si estamos en un proyecto MAVEN y ejecutamos un main dentro de Eclipse, hay que tener en cuenta que las clase se guardan en el directorio target y por tanto para obtener la carpeta que incluye a la carpeta que es nuestro proyecto, tenemos que subir 2 veces en el árbol de directorios:

    String path = aClass.getResource(aClass.getSimpleName() + ".class").getPath();
    String jarFilePath = path.substring(path.indexOf(":") + 1, path.indexOf("!"));
    jarFilePath = URLDecoder.decode(jarFilePath, "UTF-8");
    jarFile = new File(jarFilePath);
    String s=jarFile.getParentFile().getAbsolutePath();
    if (s.endsWith(File.separator+"target")) { // Maven target directory for 
                                               // compiled classes
s=s.substring(0, s.lastIndexOf(File.separator));
s=s.substring(0, s.lastIndexOf(File.separator));
    }

Finalmente si creamos una clase de utilidades nos queda:


 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
package ximodante.utils;

import java.io.File;
import java.lang.invoke.MethodHandles;
import java.net.URLDecoder;
import java.security.CodeSource;

public class FileUtils {

 /**
  * Folder that contains jar file or folder that contains project folder
  * @return
  * @throws Exception
  */
 public static String getJarContainingFolder() throws Exception {
  Class<?> aClass=MethodHandles.lookup().lookupClass();
  CodeSource codeSource = aClass.getProtectionDomain().getCodeSource();

  File jarFile;

  if (codeSource.getLocation() != null) {
   jarFile = new File(codeSource.getLocation().toURI());
  } else { // It is not a Jar file 
   String path = aClass.getResource(aClass.getSimpleName() + ".class").getPath();
      String jarFilePath = path.substring(path.indexOf(":") + 1, path.indexOf("!"));
      jarFilePath = URLDecoder.decode(jarFilePath, "UTF-8");
      jarFile = new File(jarFilePath);
  }
  String s=jarFile.getParentFile().getAbsolutePath();
  System.out.println("S------>:" + s);
  if (s.endsWith(File.separator+"target")) { // Maven target directory for compiled classes
   s=s.substring(0, s.lastIndexOf(File.separator));
   s=s.substring(0, s.lastIndexOf(File.separator));
  } 
  return s;
 }
 
 /**
  * test in main class
  * @param args
  */
 public static void main(String[] args) {
  try {
   System.out.println(getJarContainingFolder());
   System.out.println(System.getProperty("java.class.path"));
   System.out.println(System.getProperty("user.dir"));
  } catch (Exception e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  }

 }

}


viernes, 29 de diciembre de 2017

Java 9 con Eclipse: Morir en el intento!

1. Instalar Java 9

Me decanté a probar Java porqué quería hacer una bitácora (log) donde saliera la traza de los programas que llaman a un último método de la clase y en caso de error saber que había pasado.

Tras leer en Stack Overflow la manera de recuperar toda la traza de clases y metodos encadenados que apuntan a un método concreto, me recomiendan utilizar StackWalking API de Java 9 por un tema de rendimiento.

Me pongo a instalar java 9 en Ubuntu tal y como dice Shahrukh Aslam siguiendo sus pasos:


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
#download repository
sudo add-apt-repository ppa:webupd8team/java

#update reposotory
sudo apt-get update

#install
sudo apt install oracle-java9-installer

#make this java version default
sudo apt install oracle-java9-set-default

pero cuando hago java -version me llevo la sorpresa de que todavía se apunta a Java 1.8

Para ello recurro a la respuesta de SkyWalker de Stack Overflow.

OJO: Hay que tomar estas precauciones:

1. Crear un usuario nuevo por si os equivocais al manipular las variables de entorno y no se cargan, poder acceder al sistema mediante este usuario.

2. Cambiar solo el .bashrc    Para ello indicar


export JAVA_HOME=/usr/lib/jvm/java-9-oracle
export PATH=$JAVA_HOME/bin:$PATH

3. No tocar el etc/enviroment



Por desgracia toqué el etc/environment y cuando hacía login al sistema no entraba. Creia que se había cargado el teclado inglés pero no aparecía ninguna indicación. Tuve que entrar en ALT-F1 en una tty a modo caracter donde no reconocía ningun path y tuve que teclear 

/usr/bin/vi /etc/environment

Dejar el fichero tal como estaba antes y guardar con Mayuscula zz

Y pude entrar de nuevo al sistema

UFFFFFFF que alivio.

2. Que pasa con Eclipse?


Parece ser que las versiones ya instaladas de Eclipse no funcionan o funcionana a medias según de donde se las llama.

Para que funcionen las versiones antiguas hay que apuntar a la JDK de versión anterior.

Parece ser que la nueva versión de Eclipse Oxygen v2, si que funciona... pero...

1. Hay que instalar previamente el JDK 9 antes que el Eclipse.

2. Como se te ocurra ejecutar eclipse antes de instalar java 9 estás perdido. Si lo jaces hay que borrar el directorio donde has descomprimido el jar y volverlo a crear mediante la descompresión del jar (de eclipse), una vez ya haya sido instalado el jdk 9.

3. En el caso anterior, el error que salía decía "an error has occurred. See log null" o algo parecido.

4. Boton drecho sobre el proyecto -> Propiedades->Project facets y Java Compiler->Verificar que haga referencia a java 9

5. JDK 9 no muestra las librerias que pueden podrían pertenecer a JEE :
  - java.xml.ws ( SAAj, Web Services Metadata) ,
  - java.xml.bind (jAXB), java.activation (jAF),
  - java.xml.ws.annotation (Common Annotations),
  - java.corba (CORBA),
  - java.transaction (jTA),
  - java.se.ee (aggregator module for last 6 modoules),
  - jdk.xml.ws (Tools for jAX-WS, wsgen, wsimport),
  - jdk.xml.bind (Tools for jAXB, schemagen, xjc),
  - java.corba (idlj, orbd, servertoo, tnamesrv).

Por ello se habla de las siguientes RIs o implementaciónes de referencia que se encuentran en Maven:

    - com.sun.xml.ws: jaxws-ri (para jAX-WS. SAAj y Web Services Metadata) que en Maven es:
    - com.sun.xml.bind : jax-ri (JAXB)
    - javax.transaction : javax.transaction-api

Que en definitiva se pueden indicar en el pom.xml como:
    
    <properties>
       <jax.version>2.3.0</jax.version>
    </properties>

    <dependency>
      <groupId>com.sun.xml.ws</groupId>
      <artifactId>jaxws-ri</artifactId>
      <version>${jax.version}</version>
      <type>pom</type>
    </dependency>
    
    <dependency>
      <groupId>com.sun.xml.bind</groupId>
      <artifactId>jaxb-ri</artifactId>
      <version>${jax.version}</version>
      <type>pom</type>
    </dependency>
    
    <dependency>
      <groupId>javax.transaction</groupId>
      <artifactId>javax.transaction-api</artifactId>
      <version>1.2</version>
    </dependency>
    
     <dependency>
      <groupId>javax.annotation</groupId>
      <artifactId>javax.annotation-api</artifactId>
      <version>1.2</version>
    </dependency>


Hemos puesto la versión 2.3.0 en propiedades para que la cosa quede mas bonita.

Pero ....

1. Hay que tener en cuenta que estas referencias apuntan a

http://repo1.maven.org/maven2

Pero no hace falta añadirlo, ya que tambien están en el repositorio de Maven que apunta eclipse.

Si se quiesiera añadir este repositori se podría también añadir . Para ello se puede ver lo que se dice en StackOverflow y darle esta entrada al pom.xml anadada en <project>

  <repositories>
    <repository>
        <id>maven-central-repo1</id>
        <name>Maven Centra Repo1 Repository</name>
        <url>http://repo1.maven.org/maven2</url>
    </repository>

  </repositories>

2. Observar  <type>pom</type>, en su ausencia NO encuentra la dependencia !!!


3. Lombok no me funciona..

He bajado la version "cutting-edge" v1.16.19 "Edgy Guinea Pig". He ejecutado:

sudo java -jar lombok-edge.jar 

y lo he reinnstalado al Eclipse Oxygen 2. Y ... parece ser que ya lo coge!


4. Apache CXF no funciona...

De momento no tengo solución para esto. Tendré que volver a la java 1.8

Para ello la cambio con

sudo update-alternatives --config java

jueves, 21 de diciembre de 2017

A repasar Inglés (palabras nuevas sacadas de stack overflow)



A


ado: lío, alboroto, jaleo, mucho ruido y pocas nueces
ailing: enfermo, descompuesto
ain't: contranción de "am not" o "is not"
allotted: assignado, distribuido.

B

badge: distintivo, insignia, emblema
ballot: votación, encuesta. Votar, encuestar.
beet: remolacha
beetle: escarabajo
bespoke: confeccionado a medida (bespoke solution)
bias for, bias against, biased: ser partidario de, estar en contra de, tener predilcción o perjuicios por, 
blanket: frazada, cubierta
bloated: inflado, desmesurado, (the good, the bad and the bloated ?)
bloom: floración.
blur: empañar, desdibujarse.
buddy: colega, camarada.

C

cheat: trampa engaño, hacer trampa engañar. OJO: cheatsheet es guia de instruciones rápida
cluster: grupo, racimo (cluster de servidores)
clutter: follón, desbarajuste, desorden.
clutter up: Enfollonar, desbarajustar

currying: Currificar o proceso mediante el cual se descompone una función de n variables en n composiciones de funciones ( o secuencia de funciones) de una variable. Por ejemplo: una función que recibe 2 parámetros y devuelve otro: F(x,y) ->z se currifica como Una función que toma un parámetro x, y devuelve una función que toma el parámetro y y devuelve z. 
Es decir Curry(F)=F'(x)->(G'(y)->z) 


D

dagger: daga, puñal
dangling: colgante, que cuelga
disguise (in disguise) : disfrazado, camuflado
docker: estibador, cargador

E

eschew: evitar, renunciar

F

filthy: sucio, asqueroso, indedente.
flush: descarga
flyby: vuelo de reconocimiento, preliminares
foe: enemigo, oponente

G

get away with: salirse de rositas de algo
gnat: mosquito.
godsend: don de Dios, bendición, regalo de Dios.
growl: gruñido, graznido

H

havoc: lío, caos, confusion
heal: curarse
hood: capucha, toldo. Under the hood (intrínsecamente). Mirar el interior
hype: bombo publicitario, despliegue publicitario. Promocionar, publicitar

I

impingement: impacto
inapt: inapropiado

L

limb: extremidad, miembro, rama

M

meandering: serpenteante, disperso o divagante (en un discurso)
mod : complementos (de un juego). Persona nacido en los 60 y es elegante.
mood: humor (bad mood)
mud: cieno, lodo

N

nifty: genial, excelente.

O

onset: comienzo, arranque
opinionated: obstinado, terco, testarudo.
outage: corte de luz (o cualquier otro suministro)
outrageous: indignante, cabreante. escandaloso.
overhead: gastos generales, precauciones (take you overhead to copy the information)

P

patchy: desigual, disperso
portmanteau: palabra compuesta (qubit is a portmanteau or quantum anf bit), equipaje.
probe: rastrear indagar
probing: investigación, sondeo
pull up: frenar, parar, reprender (pull a service up)

Q

quandary: dilema, disyuntiva (in a quandary)

R

rave about: alabar con entusiasmo, delirar.
realm: dominio, reino.
recap: resumen, recapitulación (recap and cheat sheet:  is a concise set of notes used for quick reference)
reel: carrete. Tambalearse
robin: petirrojo
round-robin: carta en cadena, cadena de cartas, mensaje circular.

S

scale: escalar, balancear (un servicio)
spin up: poner al dia, poner a punto, sincronizar
stage: escenario, paso (multi-stage, en muchos pasos o fases)
           montar, manipular, preparar. (this stages your files locally for commit: prepara/monta los ficheros locales para el commit
staging: preparación, puesta en escena.
starch: almidón. (no confundir con stash)
start over: volver a empezar.
stash: reserva oculta, alijo. Ahorrar, guardar almacenar (stash some money away for holidays)
stem: tallo, tija
stunt: escena peligrosa, acrobacia. Artimaña, estrategia. Atrofiar, impedir, dificultar.
sucrose: sacarosa
surveillance: vigilancia
swarm: nube, enjambre, plaga (en docker swarm es una nube)

T

take down: Desmontar, desmantelar (take down an application: Desmontar una aplicacion (en ejecución))
tear down: Derribar, parar (tear down a service: parar un servicio).
tenant: Arrendatario, inquilino. Se usa en Oracle que dice que "Multitenant" 
tuck smth away: empaquetar, zamparse, endiñar.
tweak: pellizcar, modificar. Pellizco, modificaciones

V

vanquish: derrotar, vencer
venue: lugar, sitio, campo, estadio

W

wasp: avispa
weep out: eliminar, barrer del mapa
whim: antojo, capricho: ( this can be deleted at a whim )
whoop: hurras, vivas. Gritar de alegría.

jueves, 14 de diciembre de 2017

Reducir el tamaño de imagenes JPG de los móviles a 250K sin perder casi información en Ubuntu


0. Instrucciones Generales

NOTA a Noviembre de 2019: Si se convierten las imágenes desde PDF a jpg, puede haber problemas ya que algunas no se coinvierten bien con este método.
Para tratamiento de PDF se pueden obtener buenos resultados en I Love PDF


1. Para instalar en Ubuntu:

sudo apt-get install jpegoptim

2. Descargar las fotos del movil u otro sitio y realizar una copia de seguridad de los ficheros que se van a tratar, por si no sale bien la cosa. Ir a la carpeta donde estan las imágenes y para convertirlas a 256 K que da resultados aceptables si son documentos (No da buenos resutados en fotografías), teclear

jpegoptim --size=256 *.jpg  para todos los ficheros de la carpeta o

jpegoptim --size=256 image01.jpg  solo para el fichero image01.jpg



También se puede probar con 512 ó 1024 en caso que no se vean bien.


4. Si se quieren convetitr a PDF,se tendrá que instalar

sudo apt-get install imagemagick

5. Este programa comprime todas las imágenes que le indicamos en un único fichero

convert file01.jpg, file02.jpg file.pdf

convert *.jpg file.pdf


6. Se puede utilizar la opción de rotar

convert -rotate 90 file01.jpg, file02.jpg file.pdf

7. Se pueden aplicar mas opciones. Ver imagemagick


8. Pueden haber problemas al convertir a pdf. Si aparece:

convert: not authorized `Selection.pdf' @ error/constitute.c/WriteImage/1028.

Entonces en askubuntu recomiendan modificar el fichero:

/etc/ImageMagick-6/policy.xml

y cambiar

PDF rights desde none a read|write


9. También se puede cambiar de formato:

Para convertir pdf a jpg :  convert pantalla.pdf pantalla.jpg
Para convertir jpg a png : convert pantalla.jpg pantalla.png


10. Para no tener problemas con los ficheros con un caracter en blanco en el nombre, se pueden cambiar los espacios en blanco por un guión "-" en un  directorio y sus hijos, situandose en el directorio y ejecutando

rename 's/ /-/g' *


1. Ejemplo

Se me ha dado un pen drive con algunos ficheros PDF, y se quiere reducir de tamaño. Para ello se realizan los siguientes cambios:

1. Hacer una copia de seguridad de los ficheros por si acaso.

2. Sustituir los espacios en blanco por guiones en el nombre de los ficheros

rename 's/ /-/g' *

3. Convertir los ficheros con extensión pdf a jpg con una resolución de 300 ppp. Para ello se ejecuta

for f in *.pdf ; do convert -density 300 "$f" "${f%%.*}".jpg; done

donde:
  "$f" es el nombre del fichero
  "${f%%.*}" es el basename del fichero o nombre del fichero sin extensión
 -density 300 aplica una densidad de 300 ppp

Con ello ha convertido cada PDF a varios JPG, uno por cada página

4. Reducir el tamaño perdiendo algo de calidad para todos los JPG. Para ello tecleamos

jpegoptim --size=256 *.jpg

5. Observamos como se quedan, y volvemos a convertir a PDF, para ello agrupamos todos los ficheros con JPG y el basename del fichero PDF
 anterior y le añadimos -CONV al basename

for f in *.pdf ; do convert "${f%%.*}"*.jpg "${f%%.*}"-CONV.pdf; done