Чтение монохроматического растрового изображения с помощью Arduino для построения графика

Полный новичок здесь.

Я следую этой теме: Как читать растровое изображение на Arduino

В частности, третий ответ от : frarugi87 в моей попытке построить монохроматическое растровое изображение с помощью плоттерного устройства. В основном: растровое изображение>плата SD - карты>>arduino uno>>> нанесенное изображение >>>

Я попытался изменить их код для работы с монохроматическими растровыми изображениями и удалил функцию печати в файл:

    // MODIFIED CODE FROM BELOW CONTRIBUTOR

    // (c) Michael Schoeffler 2016, http://www.mschoeffler.de



    #include <SD.h> //Load SD library
    int chipSelect = 4; //chip select pin for the MicroSD Card Adapter
    File file; // file object that is used to read and write data

int32_t readNbytesInt(File *p_file, int position, byte nBytes)  // FUNCTION WHICH READS A DETERMINED AMMOUNT OF BYTES INTO A SINGLE VARIABLE 
{
    if (nBytes > 4)
        return 0;

    p_file->seek(position);

    int32_t weight = 1;
    int32_t result = 0;
    for (; nBytes; nBytes--)
    {
        result += weight * p_file->read();
        weight <<= 8;
    }
    return result;
}






    void setup() {
      Serial.begin(9600); // start serial connection to print out debug messages and data

      pinMode(chipSelect, OUTPUT); // chip select pin must be set to OUTPUT mode
      if (!SD.begin(chipSelect)) { // Initialize SD card
        Serial.println("Could not initialize SD card."); // if return value is false, something went wrong.
      }

      if (SD.exists("bitmap.bmp")) { // if "bitmap.bmp" exists, say so
        Serial.println("Found The Bitmap File.");

      }

      file = SD.open("bitmap.bmp", FILE_READ);   // open the file to an object for reading

      // DETERMINE HOW LARGE THE BITMAP FILE IS
      int howmany;
      howmany = file.available();
      Serial.println(howmany);    // print the how large the file is 



      // DETERMINE STARTING IMAGE ARRAY LOCATION IN THE BITMAP FILE
      int32_t dataStartingOffset = readNbytesInt(&file, 0x0A, 4); 
      Serial.println("The starting location in the fiile is...");
      Serial.println(dataStartingOffset);


      // DETERMINE THE IMAGE HEIGHT AND WIDTH
      int32_t imgwidth = readNbytesInt(&file, 0x12, 4);
      Serial.println("The image width is the following pixels:");
      Serial.println(imgwidth);
      int32_t imgheight = readNbytesInt(&file, 0x16, 4);
      Serial.println(imgheight);


      // MODIFIED CODE. DOES THE COLOR DEPTH LOCATION WORK IN THE BITMAP AND DOES IT GIVE CORRECT INFO ABOUT THE FILE?
      int16_t pixelsize = readNbytesInt(&file, 0X1C, 2);
      if (pixelsize != 24)
      { 
        Serial.println("This image is most definitely not 24 bpp");
        Serial.println(" it is actually a depth of :");
        Serial.println(pixelsize);

      }


       file.seek(dataStartingOffset);   //skip bitmap header and go directly to the image data array. 


     /*  for(int32_t i = 0; i < imgheight; i ++) {
        for (int32_t j = 0; j < imgwidth; j ++) {
            B = file.read();
            Serial.println("height and width location from bottom");
            Serial.println(i);
            Serial.println(j);
            Serial.println("B");
            Serial.println(B);
        }
        Serial.println("height advance");
    }


*/
      int B;

      B = file.read();
      Serial.println(B, BIN);
      B = file.read();
      Serial.println(B, BIN);


      B = file.read();
      Serial.println(B, BIN);
      B = file.read();
      Serial.println(B, BIN);



      B = file.read();
      Serial.println(B, BIN);
      B = file.read();
      Serial.println(B, BIN);


      B = file.read();
      Serial.println(B, BIN);
      B = file.read();
      Serial.println(B, BIN);

            B = file.read();
      Serial.println(B, BIN);
      B = file.read();
      Serial.println(B, BIN);


      B = file.read();
      Serial.println(B, BIN);
      B = file.read();
      Serial.println(B, BIN);



      B = file.read();
      Serial.println(B, BIN);
      B = file.read();
      Serial.println(B, BIN);


      B = file.read();
      Serial.println(B, BIN);
      B = file.read();
      Serial.println(B, BIN);

        B = file.read();
      Serial.println(B, BIN);
      B = file.read();
      Serial.println(B, BIN);

            B = file.read();
      Serial.println(B, BIN);
      B = file.read();
      Serial.println(B, BIN);


      B = file.read();
      Serial.println(B, BIN);
      B = file.read();
      Serial.println(B, BIN);



      B = file.read();
      Serial.println(B, BIN);
      B = file.read();
      Serial.println(B, BIN);


      B = file.read();
      Serial.println(B, BIN);
      B = file.read();
      Serial.println(B, BIN);

            B = file.read();
      Serial.println(B, BIN);
      B = file.read();
      Serial.println(B, BIN);


      B = file.read();
      Serial.println(B, BIN);
      B = file.read();
      Serial.println(B, BIN);



      B = file.read();
      Serial.println(B, BIN);
      B = file.read();
      Serial.println(B, BIN);


      B = file.read();
      Serial.println(B, BIN);
      B = file.read();
      Serial.println(B, BIN);

        B = file.read();
      Serial.println(B, BIN);
      B = file.read();
      Serial.println(B, BIN);



    file.close();

    Serial.println("done write");


    }

Но когда я читаю монохроматическое растровое изображение 16x16: см. Ниже

В том, что я предполагаю, является начальным местоположением таблицы цветов (заданным переменной dataStartingOffset). Я получаю строки с двумя байтами правильной информации о цвете, за которыми следуют два байта просто...нулей. Это что, растровое форматирование?

Последовательный выход для растрового изображения 16x16 выглядит следующим образом:(только до 9 из 16 строк, начинающихся снизу)

Нашел Файл Растрового Изображения. 126 Начальное расположение в файле... 62 Ширина изображения составляет следующие пиксели: 16 16 Это изображение, скорее всего, не 24 bpp это на самом деле глубина : 1 1111111 11111110 0 0 11111111 11111111 0 0 11111111 11111111 0 0 11111111 11111111 0 0 11111111 11111111 0 0 11111111 11111111 0 0 11111111 11111111 0 0 11111111 11111111 0 0 1111111 11111110 0 0 сделано написать

И когда я пытаюсь прочитать растровое изображение, которое составляет около 200 x 200 пикселей, я получаю очень странные цифры высоты и ширины, которые отрицательны, и мой приведенный выше код вообще не работает! Имеет ли растровое изображение 16x16 другое форматирование байтовой структуры, чем 200x200?

Любая помощь ценится. Опять же, я здесь полный новичок. Я просто пытаюсь понять, как читать растровое изображение.

, 👍1

Обсуждение

работал ли код до того, как вы начали его изменять?, @jsotola

проверьте формат файла растрового изображения здесь.... https://hexed.it/, @jsotola

Этого я не знаю. Он дает мне правильные значения для монохроматического растрового изображения 16x16 (ну...включая ненужные нули), и код кажется простым, но я никогда не тестировал его с цветным растровым изображением. Я предполагаю, что человек проверил свой код перед публикацией., @cheetahchips

никогда ничего не предполагайте, но код в этом ответе очень хорошо отформатирован, так что я бы тоже склонен ему доверять ... как я и подразумевал в своем первом комментарии, запустите код без изменений, @jsotola

Таблица формата файла BMP..... http://www.ue.eti.pg.gda.pl/fpgalab/zadania.spartan3/zad_vga_struktura_pliku_bmp_en.html, @jsotola

Я согласен с этим. Проверьте, работает ли код первым. Завтра я попробую это сделать с цветным растровым изображением и посмотрю, что получится., @cheetahchips


1 ответ


0

Файлы растровых изображений (.BMP) должны иметь размер строки, кратный 4 байтам. Любое дополнительное пространство в ряду должно быть заполнено 0.

Так как ваши строки имеют ширину 16 пикселей, что равняется 2 байтам. Это не кратно 4, поэтому он дополнен байтами до 0, чтобы сделать его кратным 4.

Ваш код должен учитывать это и знать, что если он не прочитал несколько 4 байт, то для чтения достаточно "пустых" байтов, чтобы перейти к началу следующей строки.

Кроме того, обратите внимание, что BMP-файлы являются единственными файлами в известной вселенной, в которых данные изображений хранятся вверх ногами (начиная с левого нижнего угла вместо левого верхнего угла).

,

ах. В этом есть смысл. Спасибо за разъяснение. Есть идеи , почему у меня может возникнуть путаница с более крупными растровыми изображениями, такими как 200x200? Таблица цветов "начальная позиция" заканчивается очень большим отрицательным числом, использующим код, который я опубликовал., @cheetahchips

Растровые изображения бывают в различных форматах данных. Вы должны изучить заголовок, чтобы узнать, какого он типа. [Здесь](https://github.com/DisplayCore/BMPFile) - это библиотека для моей системы chipKIT DisplayCore (не работает с Arduino, только chipKIT), но не стесняйтесь брать из нее то, что вам нравится., @Majenko

Боковая заметка, постскриптум и PDF-файл также имеют начало (0,0) в левом нижнем углу определенной области страницы. Можно было бы возразить, что это не форматы изображений, но они действительно описывают "чернила" на "странице", @jose can u c