Medios de desarrollo de aplicaciones de Hongmeng (imagen)

1. Conceptos básicos

  • Decodificación de imágenes

    La decodificación de imágenes es la decodificación de imágenes en diferentes formatos de archivo (como JPEG, PNGetc.) en formatos de mapa de bits sin comprimir para facilitar el procesamiento correspondiente en aplicaciones o sistemas.

  • PixelMap

    PixelMapEs un formato de mapa de bits sin comprimir después de la decodificación de imágenes, que se utiliza para la visualización de imágenes o su procesamiento posterior.

  • Decodificación progresiva

    La decodificación progresiva es un modo en el que los datos completos del archivo de imagen no se pueden proporcionar a la vez. Con el aumento gradual de los datos del archivo de imagen, la decodificación de imágenes se completa gradualmente a través de múltiples decodificaciones incrementales.

  • Premultiplicado

    Cuando se premultiplica, RGBel valor de cada canal se reemplaza con el valor original multiplicado por la proporción de opacidad del canal Alfa ( 0~1), lo que es conveniente para la síntesis directa y la superposición en la etapa posterior; no premultiplicado significa que RGBel valor de cada canal es el valor original de la imagen y Alphael valor del canal Irrelevante.

  • Codificación de imágenes

    La codificación de imágenes consiste en codificar el formato de mapa de bits sin comprimir en imágenes en formato de archivo ( JPEG, PNGetc.) en diferentes formatos para facilitar el procesamiento correspondiente en la aplicación o sistema.

Restricciones y restricciones

  • Para liberar recursos locales a tiempo, se recomienda llamar activamente al método después de utilizar el ImageSourceobjeto de decodificación de imagen, el PixelMapobjeto de imagen de mapa de bits o el ImagePackerobjeto de codificación de imagen .release()

Dos, decodificación de imágenes

La decodificación de imágenes consiste en decodificar imágenes archivadas en formatos compatibles en PixelMapimágenes unificadas para su posterior visualización de imágenes u otro procesamiento, como rotación, escalado y recorte. Formatos soportados actualmente incluyen JPEG, PNG, GIF, HEIF, WebP,BMP

La decodificación de imágenes se utiliza principalmente ImageSourcey sus interfaces comunes son las siguientes

Nombre de la interfaz descripción
crear (String pathName, opciones de SourceOptions) Cree una fuente de datos de imagen a partir de la ruta del archivo de imagen.
crear (InputStream es, SourceOptions opta) Cree una fuente de datos de imagen a partir del flujo de entrada.
crear (byte [] datos, opciones de SourceOptions) Crea una fuente de imagen a partir de una matriz de bytes.
create (byte [] datos, int offset, int length, opciones de SourceOptions) Cree una fuente de imagen a partir del rango especificado de la matriz de bytes.
crear (archivo de archivo, opciones de SourceOptions) Cree una fuente de datos de imagen a partir de un objeto de archivo.
crear (FileDescriptor fd, opciones de SourceOptions) Cree una fuente de datos de imagen a partir del descriptor de archivo.
createIncrementalSource (opciones de SourceOptions) Cree una fuente de datos de imagen progresiva.
createIncrementalSource (opciones de IncrementalSourceOptions) Crea una fuente de datos de imagen progresiva, admite la configuración del modo de actualización de datos progresiva.
createPixelmap (opciones de DecodingOptions) Decodifica y crea una imagen PixelMap a partir de la fuente de datos de la imagen.
createPixelmap (índice int, opciones DecodingOptions) Decodifica y crea una imagen PixelMap a partir de la fuente de datos de la imagen. Si la fuente de datos de la imagen admite varias imágenes, se admite el índice de imagen especificado.
updateData (byte [] datos, booleano isFinal) Actualice los datos de origen de la imagen progresiva.
updateData (byte [] datos, int offset, int length, boolean isFinal) Actualice los datos de la fuente de imagen progresiva, admite la configuración del rango de datos válido de los datos de entrada
getImageInfo () Obtenga información básica sobre imágenes.
getImageInfo (índice int) Obtenga información básica de la imagen según un índice específico.
getSourceInfo () Obtén información sobre la fuente de la imagen.
lanzamiento() Libera los recursos locales asociados con el objeto.

Desarrollo ordinario

El proceso de desarrollo es el siguiente

/**
 * @description 普通模式解码
 * @author PengHuAnZhi
 * @date 2021/1/17 13:23
 */
private void testNormalImgDecode() {
    
    
    /**
     *1、
     *   创建图像数据源ImageSource对象,可以通过SourceOptions指定数据源的格式信息,此格式信息仅为给解码器的提示,正确提供能帮助提高
     *   解码效率,如果不设置或设置不正确,会自动检测正确的图像格式。不使用该选项时,可以将create接口传入的SourceOptions设置为null。
     */
    ImageSource.SourceOptions srcOpts = new ImageSource.SourceOptions();
    srcOpts.formatHint = "image/png";
    String pathName = "/path/to/image.png";
    ImageSource imageSource = ImageSource.create(pathName, srcOpts);
    //也可以设置为空
    ImageSource imageSourceNoOptions = ImageSource.create(pathName, null);
    /**
     * 2、
     * 设置解码参数,解码获取PixelMap图像对象,解码过程中同时支持图像处理操作。设置desiredRegion支持按矩形区域裁剪,如果设置为全0,则不
     * 进行裁剪。设置desiredSize支持按尺寸缩放,如果设置为全0,则不进行缩放。设置rotateDegrees支持旋转角度,以图像中心点顺时针旋转。如果只
     * 需要解码原始图像,不使用该选项时,可将给createPixelMap传入的DecodingOptions 设置为null。
     */
    // 普通解码叠加旋转、缩放、裁剪
    ImageSource.DecodingOptions decodingOpts = new ImageSource.DecodingOptions();
    decodingOpts.desiredSize = new Size(100, 2000);
    decodingOpts.desiredRegion = new Rect(0, 0, 100, 100);
    decodingOpts.rotateDegrees = 90;
    PixelMap pixelMap = imageSource.createPixelmap(decodingOpts);
    //3、普通解码
    PixelMap pixelMapNoOptions = imageSource.createPixelmap(null);
    //4、解码完成获取到PixelMap对象后,可以进行后续处理,比如渲染显示等。
    //这里直接让一个image控件显示
    mTestImg.setPixelMap(pixelMapNoOptions);
}

Decodificación progresiva

/**
 * @description 渐进模式解码
 * @author PengHuAnZhi
 * @date 2021/1/17 13:34
 */
private void testGradualImgDecode() {
    
    
    /**
     * 1、
     * 创建渐进式图像数据源ImageSource对象,可以通过SourceOptions指定数据源的格式信息,此格式信息仅为提示,如
     * 果填写不正确,会自动检测正确的图像格式,使用IncrementalSourceOptions指定图像数据的更新方式为渐进式更新。
     */
    ImageSource.SourceOptions srcOpts = new ImageSource.SourceOptions();
    srcOpts.formatHint = "image/jpeg";
    ImageSource.IncrementalSourceOptions incOpts = new ImageSource.IncrementalSourceOptions();
    incOpts.opts = srcOpts;
    incOpts.mode = ImageSource.UpdateMode.INCREMENTAL_DATA;
    ImageSource imageSource = ImageSource.createIncrementalSource(incOpts);
    //2、渐进式更新数据,在未获取到全部图像时,支持先更新部分数据来尝试解码,更新数据时设置isFinal为false,当获取到全部数据后,最后一次更新数据时设置isFinal为true,表示数据更新完毕。设置解码参数同普通解码。
    // 获取到一定的数据时尝试解码,这里的第一个参数数据字节数组只是为了显示而模拟的,真实情况不是这样
    imageSource.updateData(new byte[2048], 0, 20, false);
    ImageSource.DecodingOptions decodingOpts = new ImageSource.DecodingOptions();
    PixelMap pixelMap = imageSource.createPixelmap(decodingOpts);
    mTestImg.setPixelMap(pixelMap);
    // 更新数据再次解码,重复调用直到数据全部更新完成
    imageSource.updateData(new byte[2048], 0, 20, false);
    PixelMap pixelMapNext = imageSource.createPixelmap(decodingOpts);
    mTestImg.setPixelMap(pixelMapNext);
    // 3、数据全部更新完成时需要传入isFinal为true
    imageSource.updateData(new byte[2048], 0, 20, true);
    PixelMap pixelMapFinal = imageSource.createPixelmap(decodingOpts);
    //4、解码完成获取到PixelMap对象后,可以进行后续处理,比如渲染显示等。   
    mTestImg.setPixelMap(pixelMapFinal);
}

Tres, codificación de imágenes

La codificación de PixelMapimágenes consiste en codificar imágenes en imágenes en diferentes formatos de archivo para otro procesamiento posterior, como guardar y transmitir. Actualmente, solo se admite el JPEGformato.

La codificación de imágenes se utiliza principalmente ImagePackery sus interfaces principales son las siguientes

Nombre de la interfaz descripción
crear() Cree una instancia del empaquetador de imágenes.
initializePacking (byte [] datos, opciones de PackingOptions) Inicialice la tarea de empaquetado y establezca la matriz de bytes como destino de salida después del empaque.
initializePacking (byte [] datos, int offset, opciones PackingOptions) Inicialice la tarea de empaquetado y establezca la matriz de bytes con desplazamiento como destino de salida después del empaque.
initializePacking (OutputStream outputStream, PackingOptions opta) Inicialice la tarea de empaquetado y establezca el flujo de salida como destino de salida después del empaquetado.
addImage (mapa de píxeles PixelMap) Agregue el objeto PixelMap al empaquetador de imágenes.
addImage (fuente ImageSource) Agregue la imagen en la fuente de datos de imagen ImageSource al empaquetador de imágenes.
addImage (fuente ImageSource, índice int) Agregue la imagen especificada en la fuente de datos de imagen ImageSource al empaquetador de imágenes.
finalizePacking () Complete la tarea de empaquetado de imágenes.
lanzamiento() Libera los recursos locales asociados con el objeto.

El proceso de desarrollo es el siguiente

/**
 * @description 图像编码
 * @author PengHuAnZhi
 * @date 2021/1/17 13:45
 */
private void testImgEncode() {
    
    
    //1、创建图像编码ImagePacker对象。
    ImagePacker imagePacker = ImagePacker.create();
    //2、设置编码输出流和编码参数。设置format为编码的图像格式,当前支持jpeg格式。设置quality为图像质量,范围从0-100,100为最佳质量。
    FileOutputStream outputStream = null;
    try {
    
    
        outputStream = new FileOutputStream("/path/to/packed.file");
    } catch (FileNotFoundException e) {
    
    
        e.printStackTrace();
    }
    ImagePacker.PackingOptions packingOptions = new ImagePacker.PackingOptions();
    packingOptions.format = "image/jpeg";
    packingOptions.quality = 90;
    boolean result = imagePacker.initializePacking(outputStream, packingOptions);
    //这里开始是纯为了构造一个pixel而写的,无实际意义
    ImageSource.SourceOptions srcOpts = new ImageSource.SourceOptions();
    srcOpts.formatHint = "image/png";
    String pathName = "/path/to/image.png";
    ImageSource imageSource = ImageSource.create(pathName, srcOpts);
    ImageSource imageSourceNoOptions = ImageSource.create(pathName, null);
   
    ImageSource.DecodingOptions decodingOpts = new ImageSource.DecodingOptions();
    decodingOpts.desiredSize = new Size(100, 2000);
    decodingOpts.desiredRegion = new Rect(0, 0, 100, 100);
    decodingOpts.rotateDegrees = 90;
    //结束,创建了一个pixelMap
    PixelMap pixelMap = imageSource.createPixelmap(decodingOpts);
    result = imagePacker.addImage(pixelMap);
    long dataSize = imagePacker.finalizePacking();
    //5、编码输出完成后,可以进行后续处理,比如保存、传输等。
}

Cuatro, mapa de bits

Las operaciones de mapa de bits se refieren a PixelMapoperaciones relacionadas con imágenes, como crear, consultar información, leer y escribir datos de píxeles, etc.

Las PixelMapprincipales interfaces de operación de mapa de bits son las siguientes

Nombre de la interfaz descripción
crear (opciones de InitializationOptions) Cree PixelMap según las opciones de inicialización, como el tamaño de la imagen, el formato de píxeles y el tipo alfa.
crear (int [] colores, opciones de InitializationOptions) 根据图像大小、像素格式、alpha类型等初始化选项,以像素颜色数组为数据源创建PixelMap。
create(int[] colors, int offset, int stride, InitializationOptions opts) 根据图像大小、像素格式、alpha类型等初始化选项,以像素颜色数组、起始偏移量、行像素大小描述的数据源创建PixelMap。
create(PixelMap source, InitializationOptions opts) 根据图像大小、像素格式、alpha类型等初始化选项,以源PixelMap为数据源创建PixelMap。
create(PixelMap source, Rect srcRegion, InitializationOptions opts) 根据图像大小、像素格式、alpha类型等初始化选项,以源PixelMap、源裁剪区域描述的数据源创建PixelMap。
getBytesNumberPerRow() 获取每行像素数据占用的字节数。
getPixelBytesCapacity() 获取存储Pixelmap像素数据的内存容量。
isEditable() 判断PixelMap是否允许修改。
isSameImage(PixelMap other) 判断两个图像是否相同,包括ImageInfo属性信息和像素数据。
readPixel(Position pos) 读取指定位置像素的颜色值,返回的颜色格式为PixelFormat.ARGB_8888。
readPixels(int[] pixels, int offset, int stride, Rect region) 读取指定区域像素的颜色值,输出到以起始偏移量、行像素大小描述的像素数组,返回的颜色格式为PixelFormat.ARGB_8888。
readPixels(Buffer dst) 读取像素的颜色值到缓冲区,返回的数据是PixelMap中像素数据的原样拷贝,即返回的颜色数据格式与PixelMap中像素格式一致。
resetConfig(Size size, PixelFormat pixelFormat) 重置PixelMap的大小和像素格式配置,但不会改变原有的像素数据也不会重新分配像素数据的内存,重置后图像数据的字节数不能超过PixelMap的内存容量。
setAlphaType(AlphaType alphaType) 设置PixelMap的Alpha类型。
writePixel(Position pos, int color) 向指定位置像素写入颜色值,写入颜色格式为PixelFormat.ARGB_8888。
writePixels(int[] pixels, int offset, int stride, Rect region) 将像素颜色数组、起始偏移量、行像素的个数描述的源像素数据写入PixelMap的指定区域,写入颜色格式为PixelFormat.ARGB_8888。
writePixels(Buffer src) 将缓冲区描述的源像素数据写入PixelMap,写入的数据将原样覆盖PixelMap中的像素数据,即写入数据的颜色格式应与PixelMap的配置兼容。
writePixels(int color) 将所有像素都填充为指定的颜色值,写入颜色格式为 PixelFormat.ARGB_8888。
getPixelBytesNumber() 获取全部像素数据包含的字节数。
setBaseDensity(int baseDensity) 设置PixelMap的基础像素密度值。
getBaseDensity() 获取PixelMap的基础像素密度值。
setUseMipmap(boolean useMipmap) 设置PixelMap渲染是否使用mipmap。
useMipmap() 获取PixelMap渲染是否使用mipmap。
getNinePatchChunk() 获取图像的NinePatchChunk数据。
getFitDensitySize(int targetDensity) 获取适应目标像素密度的图像缩放的尺寸。
getImageInfo() 获取图像基本信息。
release() 释放对象关联的本地资源。

开发流程如下

/**
 * @description 位图
 * @author PengHuAnZhi
 * @date 2021/1/17 13:52
 */
private void testPixelMap() {
    
    
    //创建位图对象PixelMap。
    // 指定初始化选项创建
    // 从像素颜色数组创建
    int[] defaultColors = new int[]{
    
    5, 5, 5, 5, 6, 6, 3, 3, 3, 0};
    /**
     *  可以指定的初始化选项有下面几个
     *  public AlphaType alphaType;//AlphaType是一个枚举类,其中定义了若干常量
     *  public boolean editable = false;//是否可编辑
     *  public PixelFormat pixelFormat;//描述图像像素格式,也是一个枚举类
     *  public boolean releaseSource = false;//字面意思是释放资源,我也不知道是什么
     *  public ScaleMode scaleMode;//又是一个枚举类,图像缩放效果
     *  public Size size;//大小吧
     *  public boolean useSourceIfMatch = false;//如果匹配使用资源?
     */
    PixelMap.InitializationOptions initializationOptions = new PixelMap.InitializationOptions();
    initializationOptions.size = new Size(3, 2);
    initializationOptions.pixelFormat = PixelFormat.ARGB_8888;
    PixelMap pixelMap1 = PixelMap.create(defaultColors, initializationOptions);
    // 以另外一个PixelMap作为数据源创建
    PixelMap pixelMap2 = PixelMap.create(pixelMap1, initializationOptions);
    //从位图对象中获取信息。
    long capacity = pixelMap1.getPixelBytesCapacity();
    long bytesNumber = pixelMap1.getPixelBytesNumber();
    int rowBytes = pixelMap1.getBytesNumberPerRow();
    byte[] ninePatchData = pixelMap1.getNinePatchChunk();
    //读写位图像素数据。
    // 读取指定位置像素
    int color = pixelMap1.readPixel(new Position(1, 1));
    // 读取指定区域像素
    int[] pixelArray = new int[50];
    Rect region = new Rect(0, 0, 10, 5);
    pixelMap1.readPixels(pixelArray, 0, 10, region);
    // 读取像素到Buffer
    IntBuffer pixelBuf = IntBuffer.allocate(50);
    pixelMap1.readPixels(pixelBuf);
    // 在指定位置写入像素
    pixelMap1.writePixel(new Position(1, 1), 0xFF112233);
    // 在指定区域写入像素
    pixelMap1.writePixels(pixelArray, 0, 10, region);
    // 写入Buffer中的像素
    pixelMap1.writePixels(defaultColors[0]);
}

五、图像属性解码

图像属性解码就是获取图像中包含的属性信息,比如EXIF属性

功能主要由ImageSourceExifUtils提供。

  • ImageSource
接口名 描述
getThumbnailInfo() 获取嵌入图像文件的缩略图的基本信息。
getImageThumbnailBytes() 获取嵌入图像文件缩略图的原始数据。
getThumbnailFormat() 获取嵌入图像文件缩略图的格式。
  • ExifUtils
接口名 描述
getLatLong(ImageSource imageSource) 获取嵌入图像文件的经纬度信息。
getAltitude(ImageSource imageSource, double defaultValue) 获取嵌入图像文件的海拔信息。

开发流程如下

/**
 * @description 图像属性解码
 * @author PengHuAnZhi
 * @date 2021/1/17 14:02
 */
private void testImgValueDecode() {
    
    
    //1、创建图像数据源ImageSource对象,可以通过SourceOptions指定数据源的格式信息,此格式信息仅为给
    // 解码器的提示,正确提供能帮助提高解码效率,如果不设置或设置不正确,会自动检测正确的图像格式。
    ImageSource.SourceOptions srcOpts = new ImageSource.SourceOptions();
    srcOpts.formatHint = "image/jpeg";
    String pathName = "/path/to/image.jpg";
    ImageSource imageSource = ImageSource.create(pathName, srcOpts);
    //2、获取缩略图信息。
    int format = imageSource.getThumbnailFormat();
    byte[] thumbnailBytes = imageSource.getImageThumbnailBytes();
    //3、将缩略图解码为PixelMap对象
    ImageSource.DecodingOptions decodingOpts = new ImageSource.DecodingOptions();
    PixelMap thumbnailPixelmap = imageSource.createThumbnailPixelmap(decodingOpts, false);
}

Supongo que te gusta

Origin blog.csdn.net/qq_43509535/article/details/112778407
Recomendado
Clasificación