Hongmeng Application Development Media (Image)

1. Basic concepts

  • Image decoding

    Image decoding is the decoding of pictures in different archive formats (such as JPEG, PNGetc.) into uncompressed bitmap formats to facilitate corresponding processing in applications or systems.

  • PixelMap

    PixelMapIt is an uncompressed bitmap format after image decoding, used for image display or further processing.

  • Progressive decoding

    Progressive decoding is a mode in which complete image file data cannot be provided at one time. With the gradual increase of image file data, image decoding is gradually completed through multiple incremental decoding.

  • Premultiplied

    When premultiplied, RGBthe value of each channel is replaced with the original value multiplied by the opaque ratio of the Alpha channel ( 0~1), which is convenient for direct synthesis and superposition in the later stage; non-premultiplied means that RGBthe value of each channel is the original value of the image, and Alphathe value of the channel Irrelevant.

  • Image coding

    Image coding is to encode the uncompressed bitmap format into archive format pictures ( JPEG, PNGetc.) in different formats to facilitate corresponding processing in the application or system.

Constraints and restrictions

  • In order to release local resources in time, it is recommended to actively call the method after the image decoding ImageSourceobject, bitmap image PixelMapobject or image encoding ImagePackerobject is used.release()

Two, image decoding

Image decoding is to decode archived pictures in supported formats into unified PixelMapimages for subsequent image display or other processing, such as rotation, scaling, and cropping. Currently supported formats include JPEG, PNG, GIF, HEIF, WebP,BMP

Image decoding is mainly used ImageSource, and its common interfaces are as follows

Interface name description
create(String pathName, SourceOptions opts) Create image data source from image file path.
create(InputStream is, SourceOptions opts) Create an image data source from the input stream.
create(byte[] data, SourceOptions opts) Create image source from byte array.
create(byte[] data, int offset, int length, SourceOptions opts) Create an image source from the specified range of the byte array.
create(File file, SourceOptions opts) Create an image data source from a file object.
create(FileDescriptor fd, SourceOptions opts) Create image data source from file descriptor.
createIncrementalSource(SourceOptions opts) Create a progressive image data source.
createIncrementalSource(IncrementalSourceOptions opts) Create progressive image data source, support setting progressive data update mode.
createPixelmap(DecodingOptions opts) Decode and create PixelMap image from image data source.
createPixelmap(int index, DecodingOptions opts) Decode and create a PixelMap image from the image data source. If the image data source supports multiple pictures, the specified image index is supported.
updateData(byte[] data, boolean isFinal) Update progressive image source data.
updateData(byte[] data, int offset, int length, boolean isFinal) Update progressive image source data, support setting the valid data range of input data.
getImageInfo() Get basic image information.
getImageInfo(int index) Obtain basic image information according to a specific index.
getSourceInfo() Get image source information.
release() Release the local resources associated with the object.

Ordinary development

The development process is as follows

/**
 * @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);
}

Progressive decoding

/**
 * @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);
}

Three, image coding

Image encoding is to PixelMapencode images into pictures in different archive formats for subsequent other processing, such as saving and transmission. Only the JPEGformat is currently supported .

Image coding is mainly used ImagePacker, and its main interfaces are as follows

Interface name description
create() Create an instance of the image packer.
initializePacking(byte[] data, PackingOptions opts) Initialize the packing task and set the byte array as the output destination after packing.
initializePacking(byte[] data, int offset, PackingOptions opts) Initialize the packing task and set the byte array with offset as the output destination after packing.
initializePacking(OutputStream outputStream, PackingOptions opts) Initialize the packaging task and set the output stream as the output destination after packaging.
addImage (PixelMap pixelmap) Add the PixelMap object to the image packer.
addImage (ImageSource source) Add the image in the image data source ImageSource to the image packer.
addImage(ImageSource source, int index) Add the specified image in the image data source ImageSource to the image packer.
finalizePacking() Complete the image packaging task.
release() Release the local resources associated with the object.

The development process is as follows

/**
 * @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、编码输出完成后,可以进行后续处理,比如保存、传输等。
}

Four, bitmap

Bitmap operations refer to PixelMaprelated operations on images, such as creating, querying information, reading and writing pixel data, etc.

The PixelMapmain interfaces of bitmap operation are as follows

Interface name description
create(InitializationOptions opts) Create PixelMap based on initialization options such as image size, pixel format, and alpha type.
create(int[] colors, InitializationOptions opts) 根据图像大小、像素格式、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);
}

Guess you like

Origin blog.csdn.net/qq_43509535/article/details/112778407