Mejorar el procesamiento de imágenes con la API moderna

Introducción

Históricamente, Aspose Slides tiene una dependencia de java.awt y en la API pública tiene las siguientes clases de allí:

A partir de la versión 24.4, esta API pública se declara obsoleta.

Para deshacernos de las dependencias de estas clases, añadimos la llamada “API Moderna”: la API que debe usarse en lugar de la obsoleta, cuyas firmas contienen dependencias en Bitmap. Canvas se declara obsoleta y su soporte se elimina de la API pública de Slides.

La eliminación de la API pública obsoleta con dependencias en System.Drawing será en la versión 24.8.

API Moderna

Se añadieron las siguientes clases y enumeraciones a la API pública:

  • IImage - representa la imagen raster o vectorial.
  • ImageFormat - representa el formato de archivo de la imagen.
  • Images - métodos para instanciar y trabajar con la interfaz IImage.

Tenga en cuenta que IImage es descartable (implementa la interfaz IDisposable y su uso debe envolver en using o descartarse de otra manera conveniente).

Un escenario típico de uso de la nueva API puede verse como sigue:

Presentation pres = new Presentation();
try {
    IPPImage ppImage;
    // instanciar una instancia descartable de IImage desde el archivo en disco.
    IImage image = Images.fromFile("image.png");
    try {
        // crear una imagen PowerPoint añadiendo una instancia de IImage a las imágenes de la presentación.
        ppImage = pres.getImages().addImage(image);
    } finally {
        if (image != null) image.dispose();
    }

    // agregar una forma de imagen en la diapositiva #1
    pres.getSlides().get_Item(0).getShapes().addPictureFrame(ShapeType.Rectangle, 10, 10, 100, 100, ppImage);

    // obtener una instancia de IImage que representa la diapositiva #1.
    IImage slideImage = pres.getSlides().get_Item(0).getImage(new Size(1920, 1080));
    try {
        // guardar la imagen en disco.
        slideImage.save("slide1.jpeg", ImageFormat.Jpeg);
    } finally {
        if (slideImage != null) slideImage.dispose();
    }
} finally {
    if (pres != null) pres.dispose();
}

Reemplazando código antiguo con API Moderna

En general, necesitará reemplazar la llamada al método antiguo que usa ImageIO con el nuevo.

Antiguo:

Presentation pres = new Presentation();
try {
    Bitmap slideImage = pres.getSlides().get_Item(0).getThumbnail(new Size(1920, 1080));
    FileOutputStream fos = null;
    try {
        fos = new FileOutputStream("image.png");
        slideImage.compress(android.graphics.Bitmap.CompressFormat.PNG, 100, fos);
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } finally {
        if (fos != null) {
            try {
                fos.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
} finally {
    if (pres != null) pres.dispose();
}

Nuevo:

Presentation pres = new Presentation();
try {
    IImage slideImage = pres.getSlides().get_Item(0).getImage(new Size(1920, 1080));
    try {
        slideImage.save("image.png", ImageFormat.Png);
    } finally {
        if (slideImage != null) slideImage.dispose();
    }
} finally {
    if (pres != null) pres.dispose();
}

Obteniendo una miniatura de diapositiva

Código usando una API obsoleta:

Presentation pres = new Presentation("pres.pptx");
try {
    Bitmap slideImage = pres.getSlides().get_Item(0).getThumbnail();
    FileOutputStream fos = null;
    try {
        fos = new FileOutputStream("slide1.png");
        slideImage.compress(android.graphics.Bitmap.CompressFormat.PNG, 100, fos);
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } finally {
        if (fos != null) {
            try {
                fos.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
} finally {
    if (pres != null) pres.dispose();
}

API Moderna:

Presentation pres = new Presentation("pres.pptx");
try {
    IImage slideImage = pres.getSlides().get_Item(0).getImage();
    try {
        slideImage.save("slide1.png", ImageFormat.Png);
    } finally {
        if (slideImage != null) slideImage.dispose();
    }
} finally {
    if (pres != null) pres.dispose();
}

Obteniendo una miniatura de forma

Código usando una API obsoleta:

Presentation pres = new Presentation("pres.pptx");
try {
    Bitmap shapeImage = pres.getSlides().get_Item(0).getShapes().get_Item(0).getThumbnail();
    FileOutputStream fos = null;
    try {
        fos = new FileOutputStream("shape.png");
        shapeImage.compress(android.graphics.Bitmap.CompressFormat.PNG, 100, fos);
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } finally {
        if (fos != null) {
            try {
                fos.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
} finally {
    if (pres != null) pres.dispose();
}

API Moderna:

Presentation pres = new Presentation("pres.pptx");
try {
    IImage shapeImage = pres.getSlides().get_Item(0).getShapes().get_Item(0).getImage();
    try {
        shapeImage.save("shape.png");
    } finally {
        if (shapeImage != null) shapeImage.dispose();
    }
} finally {
    if (pres != null) pres.dispose();
}

Obteniendo una miniatura de presentación

Código usando una API obsoleta:

Presentation pres = new Presentation("pres.pptx");
try {
    Bitmap[] bitmaps = pres.getThumbnails(new RenderingOptions(), new Size(1980, 1028));
    for (int index = 0; index < bitmaps.length; index++)
    {
        android.graphics.Bitmap thumbnail = bitmaps[index];
        FileOutputStream fos = null;
        try {
            fos = new FileOutputStream("slide" + index + ".png");
            thumbnail.compress(android.graphics.Bitmap.CompressFormat.PNG, 100, fos);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } finally {
            if (fos != null) {
                try {
                    fos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
} finally {
    if (pres != null) pres.dispose();
}

API Moderna:

Presentation pres = new Presentation("pres.pptx");
try {
    IImage[] images = pres.getImages(new RenderingOptions(), new Size(1980, 1028));
    try
    {
        for (int index = 0; index < images.length; index++)
        {
            IImage thumbnail = images[index];
            thumbnail.save("slide" + index + ".png", ImageFormat.Png);
        }
    }
    finally
    {
        for (IImage image : images)
        {
            image.dispose();
        }
    }
} finally {
    if (pres != null) pres.dispose();
}

Añadiendo una imagen a una presentación

Código usando una API obsoleta:

Presentation pres = new Presentation();
try {
    IPPImage ppImage = null;
    File file = new File("image.png");
    Bitmap bitmap = BitmapFactory.decodeFile(file.getAbsolutePath());
    ppImage = pres.getImages().addImage(bitmap);

    pres.getSlides().get_Item(0).getShapes().addPictureFrame(ShapeType.Rectangle, 10, 10, 100, 100, ppImage);
} finally {
    if (pres != null) pres.dispose();
}

API Moderna:

Presentation pres = new Presentation();
try {
    IPPImage ppImage;
    IImage image = Images.fromFile("image.png");
    try {
        ppImage = pres.getImages().addImage(image);
    } finally {
        if (image != null) image.dispose();
    }

    pres.getSlides().get_Item(0).getShapes().addPictureFrame(ShapeType.Rectangle, 10, 10, 100, 100, ppImage);
} finally {
    if (pres != null) pres.dispose();
}

Métodos que se eliminarán y su reemplazo en API Moderna

Presentación

Firma del método Firma del método de reemplazo
public final Bitmap[] getThumbnails(IRenderingOptions options) public final IImage[] getImages(IRenderingOptions options)
public final Bitmap[] getThumbnails(IRenderingOptions options, Size imageSize) public final IImage[] getImages(IRenderingOptions options, Size imageSize)
public final Bitmap[] getThumbnails(IRenderingOptions options, float scaleX, float scaleY) public final IImage[] getImages(IRenderingOptions options, float scaleX, float scaleY)
public final Bitmap[] getThumbnails(IRenderingOptions options, int[] slides) public final IImage[] getImages(IRenderingOptions options, int[] slides)
public final Bitmap[] getThumbnails(IRenderingOptions options, int[] slides, Size imageSize) public final IImage[] getImages(IRenderingOptions options, int[] slides, Size imageSize)
public final Bitmap[] getThumbnails(IRenderingOptions options, int[] slides, float scaleX, float scaleY) public final IImage[] getImages(IRenderingOptions options, int[] slides, float scaleX, float scaleY)

Forma

Firma del método Firma del método de reemplazo
public final Bitmap getThumbnail() public final IImage getImage()
public final Bitmap getThumbnail(int bounds, float scaleX, float scaleY) public final IImage getImage(int bounds, float scaleX, float scaleY)

Diapositiva

Firma del método Firma del método de reemplazo
public final Bitmap getThumbnail() public final IImage getImage()
public final Bitmap getThumbnail(Size imageSize) public final IImage getImage(Size imageSize)
public final Bitmap getThumbnail(float scaleX, float scaleY) public final IImage getImage(float scaleX, float scaleY)
public final Bitmap getThumbnail(IRenderingOptions options) public final IImage getImage(IRenderingOptions options)
public final Bitmap getThumbnail(IRenderingOptions options, Size imageSize) public final IImage getImage(IRenderingOptions options, Size imageSize)
public final Bitmap getThumbnail(IRenderingOptions options, float scaleX, float scaleY) public final IImage getImage(IRenderingOptions options, float scaleX, float scaleY)
public final Bitmap getThumbnail(ITiffOptions options) public final IImage getImage(ITiffOptions options)
public final void renderToGraphics(IRenderingOptions options, Canvas graphics) Will be deleted completely
public final void renderToGraphics(IRenderingOptions options, Canvas graphics, Size renderingSize) Will be deleted completely
public final void renderToGraphics(IRenderingOptions options, Canvas graphics, float scaleX, float scaleY) Will be deleted completely

Salida

Firma del método Firma del método de reemplazo
public final IOutputFile add(String path, Bitmap image) public final IOutputFile add(String path, IImage image)

ImageCollection

Firma del método Firma del método de reemplazo
public final IPPImage addImage(Bitmap image) public final IPPImage addImage(IImage image)

PPImage

Firma del método Firma del método de reemplazo
public final Bitmap getSystemImage() public final IImage getImage()

PatternFormat

Firma del método Firma del método de reemplazo
public final Bitmap getTileImage(Integer styleColor) public final IImage getTile(Integer styleColor)
public final Bitmap getTileImage(Integer background, Integer foreground) public final IImage getTile(Integer background, Integer foreground)

PatternFormatEffectiveData

Firma del método Firma del método de reemplazo
public final Bitmap getTileImage(Integer background, Integer foreground) public final IImage getTileIImage(Integer background, Integer foreground)

Se discontinuará el soporte de API para Canvas

Los métodos con Canvas se declaran obsoletos y su soporte será eliminado de la API pública.

La parte de la API que lo usa será eliminada:

Slide

Preguntas frecuentes

¿Por qué se eliminó android.graphics.Canvas?

El soporte para Canvas se está eliminando de la API pública para unificar el trabajo con renderizado e imágenes, eliminar dependencias específicas de la plataforma y pasar a un enfoque multiplataforma con IImage. Todos los métodos de renderizado a Canvas serán eliminados.

¿Cuál es el beneficio práctico de IImage comparado con BufferedImage?

IImage unifica el trabajo con imágenes raster y vectoriales y simplifica el guardado en varios formatos mediante ImageFormat.

¿Afectará la API Moderna al rendimiento de generación de miniaturas?

Cambiar de getThumbnail a getImage no empeora los escenarios: los nuevos métodos ofrecen las mismas capacidades para producir imágenes con opciones y tamaños, manteniendo el soporte para opciones de renderizado. La ganancia o pérdida específica depende del caso, pero funcionalmente los reemplazos son equivalentes.