Carga del manifiesto de imagen

Si necesitas más flexibilidad para subir imágenes a Google Earth Engine (EE) que la que proporciona la IU del editor de código o el comando upload de la herramienta de línea de comandos "earthengine", puedes hacerlo describiendo una carga de imagen con un archivo JSON conocido como "manifiesto" y con el comando upload image --manifest de la herramienta de línea de comandos.

Consulta un ejemplo completo en este ecuaderno de Google Colab, que muestra cómo subir mosaicos de imágenes como un solo recurso con un manifiesto.

Configuración única

  1. Las cargas de manifiestos solo funcionan con archivos ubicados en Google Cloud Storage. Para comenzar a usar Google Cloud Storage, crea un proyecto de Google Cloud, si aún no tienes uno. Ten en cuenta que la configuración requiere que especifiques una tarjeta de crédito para la facturación. En este momento, EE no le cobra a nadie, pero transferir archivos a Google Cloud Storage antes de subirlos a EE tendrá un costo pequeño. Para los tamaños de datos de carga típicos (decenas o cientos de gigabytes), el costo será bastante bajo.
  2. En tu proyecto, activa la API de Cloud Storage y crea un bucket.
  3. Instala el cliente de Python de Earth Engine. Incluye la herramienta de línea de comandos earthengine, que usaremos para subir datos.
  4. Para las cargas automáticas, te recomendamos que uses una cuenta de servicio de Google Cloud asociada con tu proyecto. No necesitas una cuenta de servicio para realizar pruebas, pero cuando tengas un momento, comienza a familiarizarte con su uso.

Es posible que los archivos de origen muy grandes (100 GB o más) se suban más rápido si se dividen en varias tarjetas.

IDs y nombres de los activos

Para los recursos que pertenecen al proyecto de Cloud, usa esta convención para los nombres de los recursos: projects/some-project-id/assets/some-asset-id.

Obtén información sobre los nombres de los activos de proyectos heredados y de los activos que pertenecen al usuario

En el caso de los proyectos heredados más antiguos, el nombre del activo en el manifiesto debe ser ligeramente diferente del ID del activo visible en otro lugar de Earth Engine. Para subir activos cuyos IDs comienzan con users/some_user o projects/some_project, el nombre del activo en el manifiesto debe tener la cadena projects/earthengine-legacy/assets/ al principio del ID. Por ejemplo, el ID del activo de EE users/username/my_geotiff se debe subir con el nombre projects/earthengine-legacy/assets/users/username/my_geotiff.

Sí, esto significa que los IDs como projects/some_projects/some_asset se convierten en nombres en los que se menciona projects dos veces: projects/earthengine-legacy/assets/projects/some_projects/some_asset. Esto es confuso, pero es necesario para cumplir con los estándares de la API de Google Cloud.

Cómo usar manifiestos

En el siguiente bloque de código, se muestra un manifiesto básico. Sube un archivo llamado small.tif desde un bucket de Google Cloud Storage llamado gs://earthengine-test.

{
  "name": "projects/some-project-id/assets/some-asset-id",
  "tilesets": [
    {
      "sources": [
        {
          "uris": [
            "gs://earthengine-test/small.tif"
          ]
        }
      ]
    }
  ]
}

Para usarlo, guárdalo en un archivo llamado manifest.json y ejecuta lo siguiente:

earthengine upload image --manifest /path/to/manifest.json

(El archivo gs://earthengine-test/small.tif existe y es legible de forma pública; puedes usarlo para realizar pruebas).

Conjuntos de tarjetas

La estructura de manifiesto un tanto complicada de JSON es necesaria para brindar suficiente flexibilidad para abordar un desafío de carga común: cómo describir todas las formas posibles de combinar píxeles de varios archivos de origen en un solo recurso. Específicamente, hay dos formas independientes de agrupar archivos:

  • Mosaicos A veces, varios archivos representan varias tarjetas (por ejemplo, cada tarjeta es un cuadrado de 1 × 1 grado). Estos archivos deben estar mosaicados (fusionados) en la misma banda de un recurso de EE.
  • Bandas separadas. A veces, varios archivos representan varias bandas. Estos archivos deben apilarse como bandas en un recurso de EE.

(Es posible que debas usar ambas formas al mismo tiempo, pero esa es una situación poco frecuente).

Para describir estas opciones, los manifiestos introducen el concepto de un mosaico. Un solo conjunto de mosaicos corresponde a una sola fuente de GDAL. Debido a esto, todas las fuentes de un solo conjunto de mosaicos deben tener la misma estructura de GDAL (cantidad y tipo de bandas, proyección, transformación, valor faltante). Dado que una fuente de GDAL puede tener varias bandas, un conjunto de mosaicos puede contener datos de varias bandas de EE.

Para la transferencia de mosaicos, el manifiesto se verá de la siguiente manera:

{
  "name": "projects/some-project-id/assets/some-asset-id",
  "tilesets": [
    {
      "sources": [
        {
          "uris": [
            "gs://bucket/N30W22.tif"
          ]
        },
        {
          "uris": [
            "gs://bucket/N31W22.tif"
          ]
        }
      ]
    }
  ]
}

Para bandas separadas, el manifiesto se verá así (también debes agregar una sección bands como se explica a continuación):

{
  "name": "projects/some-project-id/assets/some-asset-id",
  "bands": ...,
  "tilesets": [
    {
      "id": "tileset_for_band1",
      "sources": [
        {
          "uris": [
            "gs://bucket/band1.tif"
          ]
        }
      ]
    },
    {
      "id": "tileset_for_band2",
      "sources": [
        {
          "uris": [
            "gs://bucket/band2.tif"
          ]
        }
      ]
    }
  ]
}

Ten en cuenta que, en el caso de las bandas separadas, debemos asignar a cada conjunto de mosaicos un ID de conjunto de mosaicos diferente para mayor claridad. El ID del conjunto de mosaicos puede ser una cadena arbitraria; estas cadenas no se conservan en el activo subido. Los IDs de conjunto de mosaicos solo se usan en la transferencia para distinguir los conjuntos de mosaicos apilados entre sí.

Bandas

El segundo concepto importante es hacer coincidir los archivos de origen con las bandas de recursos de EE. Esto se hace con la sección bands del manifiesto.

Se puede omitir la sección bands, en cuyo caso las bandas se crean primero a partir de los archivos del primer conjunto de mosaicos, luego del siguiente conjunto de mosaicos, y así sucesivamente. De forma predeterminada, las bandas se denominan "b1", "b2", etc. Para anular los nombres de banda predeterminados, incluye una sección "bands" al final, como la siguiente:

{
  "name": "projects/earthengine-legacy/assets/users/username/some_folder/some_id",
  "tilesets": [
    {
      "sources": [
        {
          "uris": [
            "gs://bucket/rgb.tif"
          ]
        }
      ]
    }
  ],
  "bands": [
    {
      "id": "R",
      "tilesetBandIndex": 0
    },
    {
      "id": "G",
      "tilesetBandIndex": 1
    },
    {
      "id": "B",
      "tilesetBandIndex": 2
    }
  ]
}

La cantidad de bandas de EE debe ser la misma que la cantidad total de bandas en todos los conjuntos de mosaicos.

Si no quieres transferir todas las bandas de un archivo, puedes usar el campo tilesetBandIndex para indicar cuáles de las bandas de GDAL se deben transferir. La primera banda tiene un tilesetBandIndex de 0.

Ejemplo:

Supongamos que el archivo fuente tiene cuatro bandas: "tmin", "tmin_error", "tmax" y "tmax_error". Solo queremos transferir "tmin" y "tmax". Las secciones relevantes del manifiesto se verán de la siguiente manera:

{
  "name": "projects/earthengine-legacy/assets/users/username/some_folder/some_id",
  "tilesets": [
    {
      "id": "temperature",
      "sources": [
        {
          "uris": [
            "gs://bucket/temperature.tif"
          ]
        }
      ]
    }
  ],
  "bands": [
    {
      "id": "tmin",
      "tilesetBandIndex": 0,
      "tilesetId": "temperature"
    },
    {
      "id": "tmax",
      "tilesetBandIndex": 2,
      "tilesetId": "temperature"
    }
  ]
}

Enmascarar bandas

El componente maskBands del manifiesto controla el enmascaramiento de bandas. Se admiten tres configuraciones de máscara posibles (pero se supone que la banda de máscara siempre es la última en un archivo determinado).

  1. Oculta todas las bandas de datos en el mismo archivo.
  2. Oculta todas las bandas de datos que provienen de todos los demás archivos.
  3. Enmascara algunas bandas de datos.

1. El caso más común es un solo GeoTIFF cuya última banda se usa como máscara para las otras bandas. Esto solo funciona para GeoTIFF de tipo Byte. Usa el siguiente manifiesto:

{
  "name": "projects/earthengine-legacy/assets/users/username/some_folder/some_id",
  "tilesets": [
    {
      "id": "data_tileset",
      "sources": [
        {
          "uris": [
            "gs://bucket/data_file.tif"
          ]
        }
      ]
    }
  ],
  "bands": [
    {
      "id": "data_band",
      "tilesetId": "data_tileset"
    },
    {
      "id": "qa_band",
      "tilesetId": "data_tileset"
    }
  ],
  "maskBands": [
    {
      "tilesetId": "data_tileset"
    }
  ]
}

2. Para usar una máscara GeoTIFF como máscara para todas las bandas de otro GeoTIFF, usa el siguiente manifiesto:

{
  "name": "projects/earthengine-legacy/assets/users/username/some_folder/some_id",
  "tilesets": [
    {
      "id": "data_tileset",
      "sources": [
        {
          "uris": [
            "gs://bucket/data_file.tif"
          ]
        }
      ]
    },
    {
      "id": "mask_tileset",
      "sources": [
        {
          "uris": [
            "gs://bucket/mask_file.tif"
          ]
        }
      ]
    }
  ],
  "bands": [
    {
      "id": "data_band",
      "tilesetId": "data_tileset"
    },
    {
      "id": "qa_band",
      "tilesetId": "data_tileset"
    }
  ],
  "maskBands": [
    {
      "tilesetId": "mask_tileset"
    }
  ]
}

3. Para usar un GeoTIFF como máscara para una banda específica en otro archivo, usa el siguiente manifiesto (la diferencia con el caso anterior es que se establece el campo bandIds en maskBands):

{
  "name": "projects/earthengine-legacy/assets/users/username/some_folder/some_id",
  "tilesets": [
    {
      "id": "data_tileset",
      "sources": [
        {
          "uris": [
            "gs://bucket/data_file.tif"
          ]
        }
      ]
    },
    {
      "id": "mask_tileset",
      "sources": [
        {
          "uris": [
            "gs://bucket/mask_file.tif"
          ]
        }
      ]
    }
  ],
  "bands": [
    {
      "id": "data_band",
      "tilesetId": "data_tileset"
    },
    {
      "id": "qa_band",
      "tilesetId": "data_tileset"
    }
  ],
  "maskBands": [
    {
      "tilesetId": "mask_tileset",
      "bandIds": ["data_band"]
    }
  ]
}

En el último ejemplo, trabajamos con dos bandas del conjunto de mosaicos data_tileset, pero solo aplicamos una máscara a una de las bandas (data_band), como lo designa el campo bandIds del único objeto de lista maskBands proporcionado.

Ten en cuenta que solo se usa la última banda del conjunto de mosaicos que se menciona en maskBands como la banda de máscara.

Política de esquemas piramidales

Cuando Earth Engine construye pirámides de imágenes durante la transferencia, debe reducir repetidamente las cuadrículas de 2 × 2 píxeles en un solo píxel y transformar el valor de píxeles de alguna manera. De forma predeterminada, se calcula el promedio de los valores de píxeles, lo que es lo correcto en la mayoría de los casos cuando la banda de ráster representa datos más o menos continuos. Sin embargo, hay dos situaciones en las que confiar en la configuración predeterminada producirá resultados incorrectos, en cuyo caso se debe establecer el campo pyramidingPolicy en la definición de la banda (si no se establece, se supone que su valor es "MEAN" de forma predeterminada).

Para la clasificación de imágenes ráster (por ejemplo, para la clasificación de cobertura terrestre), la forma más lógico de crear una pirámide de píxeles es tomar la mayoría de los cuatro valores para producir el siguiente. Esto se hace con la política de piramidización "MODE":

{
  "name": "projects/earthengine-legacy/assets/users/username/some_folder/some_id",
  "tilesets": [
    {
      "sources": [
        {
          "uris": [
            "gs://bucket/landcover.tif"
          ]
        }
      ]
    }
  ],
  "bands": [
    {
      "id": "landcover",
      "pyramidingPolicy": "MODE"
    }
  ]
}

Para las bandas de trama en las que ni "MEAN" ni "MODE" tienen sentido (por ejemplo, píxeles empaquetados en bits), se debe usar la política de pirámide "SAMPLE". "SAMPLE" siempre toma el valor del píxel superior izquierdo de cada cuadrícula de 2 × 2. En el siguiente ejemplo, se asigna la política de piramidización "MEAN" a una banda que representa una variable continua ("NDVI") y "SAMPLE" a la banda "QA" de los datos.

{
  "name": "projects/earthengine-legacy/assets/users/username/some_folder/some_id",
  "tilesets": [
    {
      "sources": [
        {
          "uris": [
            "gs://bucket/ndvi.tif"
          ]
        }
      ]
    }
  ],
  "bands": [
    {
      "id": "NDVI",
      "tilesetBandIndex": 0,
      "pyramidingPolicy": "MEAN"
    },
    {
      "id": "QA",
      "tilesetBandIndex": 1,
      "pyramidingPolicy": "SAMPLE"
    }
  ]
}

Hora de inicio y finalización

Todos los recursos deben especificar la hora de inicio y finalización para brindar más contexto a los datos, especialmente si se incluyen en colecciones. Estos campos no son obligatorios, pero te recomendamos que los uses siempre que sea posible.

La hora de inicio y finalización suele referirse a la hora de la observación, no a la hora en que se produjo el archivo fuente.

Para simplificar, la hora de finalización se considera un límite exclusivo. Por ejemplo, para los recursos que abarcan exactamente un día, usa la medianoche de dos días consecutivos (por ejemplo, 1980-01-31T00:00:00 y 1980-02-01T00:00:00) para la hora de inicio y finalización. Si el activo no tiene duración, establece la hora de finalización como la misma que la de inicio. Representa las horas en manifiestos como cadenas ISO 8601. Para simplificar los valores de fecha, te recomendamos que asumas que la hora de finalización es exclusiva (por ejemplo, la medianoche del día siguiente para los recursos diarios).

Ejemplo:

{
  "name": "projects/some-project-id/assets/some-asset-id",
  "tilesets": [
    {
      "sources": [
        {
          "uris": [
            "gs://bucket/img_20190612.tif"
          ]
        }
      ]
    }
  ],
  "startTime": "1980-01-31T00:00:00Z",
  "endTime": "1980-02-01T00:00:00Z"
}

Referencia de la estructura del manifiesto

La siguiente estructura JSON incluye todos los campos de manifiesto de carga de imágenes posibles. Encuentra las definiciones de los campos en la siguiente sección de definiciones de campos del manifiesto.

{
  "name": <string>,
  "tilesets": [
    {
      "dataType": <string>,
      "id": <string>,
      "crs": <string>,
      "sources": [
        {
          "uris": [
            <string>
          ],
          "affineTransform": {
            "scaleX": <double>,
            "shearX": <double>,
            "translateX": <double>,
            "shearY": <double>,
            "scaleY": <double>,
            "translateY": <double>
          }
        }
      ]
    }
  ],
  "bands": [
    {
      "id": <string>,
      "tilesetId": <string>,
      "tilesetBandIndex": <int32>,
      "missingData": {
        "values": [<double>]
      },
      "pyramindingPolicy": <string>
    }
  ],
  "maskBands": [
    {
      "tilesetId": <string>,
      "bandIds": [
        <string>
      ]
    }
  ],
  "footprint": {
    "points": [
      {
        "x": <double>,
        "y": <double>
      }
    ],
    "bandId": <string>
  },
  "missingData": {
     "values": [<double>]
  },
  "pyramidingPolicy": <string>,
  "uriPrefix": <string>,
  "startTime": {
    "seconds": <integer>
  },
  "endTime": {
    "seconds": <integer>
  },
  "properties": {
    <unspecified>
  }
}

Definiciones de campos del manifiesto

nombre

string

Es el nombre del recurso que se creará. name tiene el formato "projects/*/assets/**" (por ejemplo, "projects/earthengine-legacy/assets/users/USER/ASSET").

conjuntos de mosaicos

list

Es una lista de diccionarios que definen propiedades para conjuntos de mosaicos. Consulta los siguientes campos de elementos del diccionario tilesets para obtener más información.

tilesets[i].dataType

string

Especifica el tipo de datos numéricos de los datos. El valor predeterminado es el tipo que informa GDAL, en cuyo caso no es necesario definirlo.

Tipo de datos Valor
Sin especificar "DATA_TYPE_UNSPECIFIED"
Número entero de 8 bits con firma "INT8"
Número entero de 8 bits sin firma "UINT8"
Número entero de 16 bits con firma "INT16"
Número entero de 16 bits sin firma "UINT16"
Número entero de 32 bits con firma "INT32"
Número entero de 32 bits sin firma "UINT32"
Número de punto flotante de 32 bits "FLOAT32"
Número de punto flotante de 64 bits "FLOAT64"

tilesets[i].id

string

Es el ID del conjunto de mosaicos. Debe ser único entre los conjuntos de mosaicos especificados en el manifiesto de recursos. Este ID se descarta durante el paso de procesamiento y solo se usa para vincular un conjunto de mosaicos a una banda. La cadena vacía es un ID válido.

tilesets[i].crs

string

Es el sistema de referencia de coordenadas de la cuadrícula de píxeles, especificado como un código estándar siempre que sea posible (por ejemplo, el código EPSG) y, de lo contrario, en formato WKT.

tilesets[i].sources

list

Es una lista de diccionarios que definen las propiedades de un archivo de imagen y sus archivos vinculados. Consulta los siguientes campos de elementos del diccionario sources para obtener más información.

tilesets[i].sources[j].uris

list

Es una lista de los URIs de los datos que se transferirán. Solo se admiten los URIs de Google Cloud Storage. Cada URI debe especificarse en el siguiente formato: gs://bucket-id/object-id. El objeto principal debe ser el primer elemento de la lista, y los Sidecar deben aparecer después. Cada URI tiene el prefijo ImageManifest.uriPrefix si está configurado.

tilesets[i].sources[j].affineTransform

dictionary

Una transformación afín opcional. Solo se debe especificar si los datos de uris (incluidos los sidecars) no son suficientes para colocar los píxeles. Se proporciona como un diccionario con las siguientes claves: "scaleX", "shearX", "translateX", "shearY", "scaleY", "translateY". Consulta esta referencia para obtener más información.

Claves y valores de ejemplo:

{
  "scaleX": 0.1,
  "shearX": 0.0,
  "translateX": -180.0,
  "shearY": 0.0,
  "scaleY": -0.1,
  "translateY": 90.0
}

bandas

list

Es una lista de diccionarios que definen las propiedades de una sola banda proveniente de un conjunto de mosaicos. Ten en cuenta que el orden de las bandas del activo es el mismo que el de bands. Consulta los siguientes campos de elementos del diccionario bands para obtener más información.

bands[i].id

string

Es el ID (nombre) de la banda.

bands[i].tilesetId

string

Es el ID del conjunto de mosaicos correspondiente a la banda.

bands[i].tilesetBandIndex

int32

Es el índice de banda basado en cero del conjunto de mosaicos correspondiente a la banda.

bands[i].missingData.values

list

Es una lista de valores (tipo doble) que no representan datos en la banda.

bands[i].pyramidingPolicy

string

La política de venta piramidal. Consulta este vínculo para obtener más información. Incluye las siguientes opciones:

  • "MEAN" (predeterminado)
  • "MODE"
  • "SAMPLE"

maskBands

list

Es una lista de diccionarios que definen las propiedades de una sola banda de máscara proveniente de un conjunto de mosaicos. Se puede proporcionar 1 banda de máscara como máximo. Consulta los siguientes campos de elementos del diccionario maskBands para obtener más información.

maskBands[i].tilesetId

string

Es el ID del conjunto de mosaicos que corresponde a la banda de la máscara. La última banda del conjunto de mosaicos siempre se usa como la banda de máscara.

maskBands[i].bandIds

list of strings

Es la lista de los IDs de las bandas a las que se aplica la banda de máscara. Si está vacía, la banda de máscara se aplica a todas las bandas del recurso. Cada banda solo puede tener una banda de máscara correspondiente.

huella

dictionary

Es un diccionario que define las propiedades de la huella de todos los píxeles válidos de una imagen. Si está vacía, el espacio en disco predeterminado es toda la imagen. Consulta los siguientes campos de elementos del diccionario footprint para obtener más información.

footprint.points

list

Es una lista de puntos que definen el espacio de todos los píxeles válidos en una imagen. Un punto se define con un diccionario que tiene las claves "x" e "y" con valores de punto flotante. Una lista de puntos para describir un anillo que forma el exterior de un polígono simple que debe contener los centros de todos los píxeles válidos de la imagen. Debe ser un anillo lineal: el último punto debe ser igual al primero. Las coordenadas están en la proyección de la banda especificada por bandId.

Nota: Usa coordenadas no enteras, como el centro de cada píxel, ya que footprint se toma para incluir un píxel si este (un rectángulo de 1 × 1) interseca la huella. Para evitar seleccionar píxeles adyacentes por accidente, no uses coordenadas con valores enteros, ya que esos son los límites entre los píxeles. Dibujar el espacio en los centros de los píxeles evita incluir píxeles no deseados, lo que puede causar errores cuando los píxeles deseados se unen a un límite del mapa, como el antimeridiano o un polo.

Por ejemplo, para una imagen de 2 × 2 con los cuatro píxeles válidos, el siguiente es un anillo posible:

[
  {
    "x": 0.5,
    "y": 0.5
  },
  {
    "x": 0.5,
    "y": 1.5
  },
  {
    "x": 1.5,
    "y": 1.5
  },
  {
    "x": 1.5,
    "y": 0.5
  },
  {
    "x": 0.5,
    "y": 0.5
  }
]

footprint.bandId

string

Es el ID de la banda cuyo CRS define las coordenadas de la huella. Si está vacío, se usa la primera banda.

missingData.values

list

Es una lista de valores (tipo doble) que no representan datos en todas las bandas de la imagen. Se aplica a todas las bandas que no especifican su propio missingData.

pyramidingPolicy

string

La política de venta piramidal. Si no se especifica, se aplica la política "MEAN" de forma predeterminada. Se aplica a todas las bandas que no especifican su propia configuración. Consulta este vínculo para obtener más información. Incluye las siguientes opciones:

  • "MEAN" (predeterminado)
  • "MODE"
  • "SAMPLE"

uriPrefix

string

Es un prefijo opcional que se agrega a todos los uris definidos en el manifiesto.

startTime

integer

La marca de tiempo asociada con el activo, si corresponde Por lo general, corresponde a la hora en la que se tomó una imagen satelital. En el caso de los recursos que corresponden a un intervalo de tiempo, como los valores promedio durante un mes o un año, esta marca de tiempo corresponde al inicio de ese intervalo. Se especifica como segundos y, de manera opcional, nanosegundos desde la época (1970-01-01). Se supone que está en la zona horaria UTC.

endTime

integer

En el caso de los recursos que corresponden a un intervalo de tiempo, como los valores promedio durante un mes o un año, esta marca de tiempo corresponde al final de ese intervalo (exclusivo). Se especifica como segundos y, de manera opcional, nanosegundos desde la época (1970-01-01). Se supone que está en la zona horaria UTC.

properties

dictionary

Un diccionario plano arbitrario de pares clave-valor. Las claves deben ser cadenas, y los valores pueden ser números o cadenas. Aún no se admiten los valores de lista para los recursos subidos por el usuario.

Limitaciones

Tamaño del manifiesto JSON

El límite de tamaño del archivo de manifiesto JSON es de 10 MB. Si tienes muchos archivos para subir, considera maneras de reducir la cantidad de caracteres necesarios para describir el conjunto de datos. Por ejemplo, usa el campo uriPrefix para eliminar la necesidad de proporcionar la ruta de acceso del bucket de Google Cloud para cada URI en la lista uris. Si se necesita una mayor reducción de tamaño, intenta acortar los nombres de archivo.

Formato de archivo de imagen

Cada archivo de imagen debe ser una imagen TIFF. Si no se especifica el CRS en el manifiesto, el archivo debe ser un GeoTIFF con un CRS incorporado.

Los archivos TIFF se pueden comprimir con DEFLATE, JPEG-XL/JXL, LERC, LERC_DEFLATE, LERC_ZSTD, LZMA, LZW, WEBP o ZSTD.

Recomendaciones para obtener la mejor experiencia de carga de archivos grandes:

  • Mejor opción: ZSTD ofrece un buen equilibrio entre velocidad y compresión.
  • Evitar: LZMA puede ser muy lento a pesar de una buena compresión.
  • Archivos sin comprimir: Se generarán archivos más grandes y tiempos de carga más largos.
  • Compresión con pérdida (p.ej., JPEG): Puede alterar los valores de píxeles. Usa compresión sin pérdida (p.ej., DEFLATE, LZMA, LZW, ZSTD), a menos que comprendas el posible impacto en tus datos.