Skip to content

Write a tiff tile-by-tile #4252

Open
Open
@jonasteuwen

Description

@jonasteuwen

Previously I attempted to use pyvips to write a (big) tiff tile-by-tile, but that is not supported yet: #2860. Since I can now map #4223 a VImage to a pyvips image, this can just as well be done in C++.

However, I am not sure if I understand completely how to do this with VIPS. With libtiff you can just do WriteTIFFTile and you're good to go. How does that work with VIPS? Do I need to iterate the tiles in Fortran order? Would something like this allow for low-memory needs?

#include <vips/vips8>

using vips::VImage;

void ProcessTiles(const std::string& input_file, const std::string& output_file, int tile_width, int tile_height) {
    // Open the input image
    VImage input = VImage::new_from_file(input_file.c_str(), vips::VImage::option()->set("access", "sequential"));

    // Get the dimensions of the image
    int width = input.width();
    int height = input.height();

    // Create a blank image to initialize the TIFF writer
    VImage output = VImage::black(width, height).cast(input.format());

    // Save the output image as a tiled TIFF
    output.tiffsave(output_file.c_str(),
                    vips::VImage::option()
                        ->set("tile", true)
                        ->set("tile_width", tile_width)
                        ->set("tile_height", tile_height)
                        ->set("compression", "jpeg")
                        ->set("bigtiff", true));

    // Process the image tile-by-tile
    for (int y = 0; y < height; y += tile_height) {
        for (int x = 0; x < width; x += tile_width) {
            // Read the current tile
            int current_tile_width = std::min(tile_width, width - x);
            int current_tile_height = std::min(tile_height, height - y);
            VImage tile = input.extract_area(x, y, current_tile_width, current_tile_height);

            // Write the tile to the output file
            output = output.insert(tile, x, y, vips::VImage::option()->set("expand", true));
        }
    }

    std::cout << "Tiled image written to: " << output_file << std::endl;
}

int main() {
    if (VIPS_INIT("tile_writer")) {
        vips_error_exit(NULL);
    }

    const std::string input_file = "big_image.tiff";
    const std::string output_file = "output_image.tiff";
    int tile_width = 256;
    int tile_height = 256;

    ProcessTiles(input_file, output_file, tile_width, tile_height);

    vips_shutdown();
    return 0;
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions