2.5 (Zusatz) 2-dim Array – Image bearbeiten#

In der Erweiterung des vorherigen Beispiels wird hier ein Bild in den Speicher geladen wird. Als Nutzer und Programmierer abstrahieren wir ein Bild als zwei-dimensionales Feld von Pixeln (bzw. mehr-dimensional wenn wir vers. Farbwerte betrachten). Im Speicher wird dies aber als ein großer 1-dimensionaler Array angelegt.

Im folgenden wird dazu eine Hilfsfunktion eingeführt zum öffnen eines Bildes aus einem BMP Format. Um das eingelesene Bild dann zu speichern oder das angepasste Bild zu speichern, werden externe Header benötigt. Dafür liegt in dem gitlab eine CPP Version zum lokalen kompilieren, mit der sie dies testen können (2_5_2dim_Image.cpp).

#include <iostream>
#include <fstream>
void loadBMPImage(const char* file_name, unsigned char**& image, int& width, int& height)
{
    // Open the BMP image file in binary mode
    std::ifstream file(file_name, std::ios::binary);

    if (!file)
    {
        std::cout << "Failed to open " << file_name << std::endl;
        return;
    }

    // Read the header of the BMP image file (54 bytes)
    char header[54];
    file.read(header, 54);

    // Extract the width and height of the image from the header
    width = *(int*)&header[18];
    height = *(int*)&header[22];

    // Calculate the number of padding bytes per row
    int padding = 0;
    while ((width + padding) % 4 != 0)
    {
        padding++;
    }

    // Calculate the total size of the image data in bytes
    int data_size = (width + padding) * height;

    // Allocate memory to store the image data
    unsigned char* data = new unsigned char[data_size];

    // Read the image data from the file into the data buffer
    file.read(reinterpret_cast<char*>(data), data_size);

    // Close the BMP image file
    file.close();

    // Create a 2D array to store the image data
    image = new unsigned char*[height];
    for (int y = 0; y < height; ++y)
    {
        image[y] = &data[(width + padding) * y];
    }
}

ToDo:

  • Implementieren sie eine Funktion, die den mittleren Graustufenwert über dem Bild berechnet.

  • Im Beispiel ist dies Bild sehr dunkel. Wie können sie dies aufhellen? Erweitern sie den Code entsprechend: Passen sie den Code so an, dass sie die Werte des Bildes im Array sinnvoll aufhellen (den Wertebereich auf das ganze Spektrum für Grauwerte von 0 bis 255 ausdehnen).

// Function to calculate the mean grayscale value of an image
double calculateMeanGrayscaleValue2d(unsigned char** image, int width, int height)
{
    double sum = 0.0;
    for (int y = 0; y < height; ++y)
    {
        for (int x = 0; x < width; ++x)
        {
            sum += image[y][x];
        }
    }
    return sum / (width * height);
}
int main()
{
    const char* file_name = "images/marie_darkened.bmp";
    unsigned char** image = nullptr;
    int width = 0;
    int height = 0;

    loadBMPImage(file_name, image, width, height);

    // Calculate the mean grayscale value of the image
    double mean = calculateMeanGrayscaleValue2d(image, width, height);
    std::cout << "Mean grayscale value: " << mean << std::endl;

    // Clean up memory
    delete[] image[0];
    delete[] image;
    return 0;
}
main();