adafruit / Adafruit_ILI9341

Library for Adafruit ILI9341 displays
398 stars 278 forks source link

getPixel() or readPixel() #55

Open AntonioFromBrazil opened 5 years ago

AntonioFromBrazil commented 5 years ago

Does anybody know how to implement a getPixel() or readPixel() for 9341 TFT controller ? I have an application where I need to save the pixel displayed at x,y location before write a new one at same location... I did not find in GFX library any function to do that...

makermelissa commented 5 years ago

Thanks for posting the issue here. :)

DrSmithLMU commented 11 months ago

Since I stumbled on this old thread and couldn't find an answer online, I figured I'd post my solution.

In the included code, I print a larger .bmp to the screen (which crops to the screen size), then read each pixel on the screen and save it to a GFXcanvas16 (requires ~150kB RAM), then show how quickly the canvas can be copied from the screen and displayed. You could use the code from inside the for loop to read an individual pixel, noting that you need to discard the first "dummy read".

// Adafruit_ImageReader test for 2.4" TFT FeatherWing. Demonstrates loading
// images from SD card or flash memory to the screen, to RAM, and how to
// query image file dimensions. OPEN THE ARDUINO SERIAL MONITOR WINDOW TO
// START PROGRAM. Requires three BMP files in root directory of SD card or
// flash: purple.bmp, parrot.bmp and wales.bmp.

#include <Adafruit_GFX.h>         // Core graphics library
#include <Adafruit_ILI9341.h>     // Hardware-specific library
#include <SdFat.h>                // SD card & FAT filesystem library
#include <Adafruit_SPIFlash.h>    // SPI / QSPI flash library
#include <Adafruit_ImageReader.h> // Image-reading functions
#include <SPI.h>

// Pin definitions for 2.4" TFT FeatherWing vary among boards...
#define TFT_CS   9
#define TFT_DC   10
#define SD_CS    5

SdFat                SD;         // SD card filesystem
Adafruit_ImageReader reader(SD); // Image-reader object, pass in SD filesys
Adafruit_Image       image;
Adafruit_ILI9341       tft    = Adafruit_ILI9341(TFT_CS, TFT_DC);

void setup(void) {

  Serial.begin(9600);
  while(!Serial)  delay(100);       // Wait for Serial Monitor before continuing

  tft.begin();          // Initialize screen

  // The Adafruit_ImageReader constructor call (above, before setup())
  // accepts an uninitialized SdFat or FatVolume object. This MUST
  // BE INITIALIZED before using any of the image reader functions!
  Serial.println(F("Initializing filesystem..."));
  // SD card is pretty straightforward, a single call...
  if(!SD.begin(SD_CS, SD_SCK_MHZ(25))) { // ESP32 requires 25 MHz limit
    Serial.println(F("SD begin() failed"));
    for(;;); // Fatal error, do not continue
  }

  tft.setRotation(1);

  reader.drawBMP("/LocalMapE5.bmp", tft, 0, 0);

  GFXcanvas16 canvas(320, 240);

  readPixelsToCanvas(&tft,&canvas,0,0,canvas.width(), canvas.height());

  tft.fillScreen(0x0000);

  tft.drawRGBBitmap(0, 0, canvas.getBuffer(), canvas.width(), canvas.height());

}

void loop() {
  ;
}

void readPixelsToCanvas(Adafruit_ILI9341* tft, GFXcanvas16* canvas, int16_t x, int16_t y, int16_t w, int16_t h) {
  tft->startWrite();
  tft->setAddrWindow(x,y,w,h);
  tft->SPI_DC_LOW(); // Command mode
  tft->spiWrite(ILI9341_RAMRD); // 0x2E 
  tft->SPI_DC_HIGH();    // Data mode
  tft->spiRead(); // dummy read
  for (int r = 0; r < h; r++) {
    for (int c = 0; c < w; c++) {
      // Serial.print(x+r); Serial.print(", "); Serial.println(y+c);
      byte red = tft->spiRead();
      red = (red >> 2) & 0b00011111; // need bits xRRRRRxx
      // Serial.print("Red:   "); Serial.println(red,BIN);
      byte green = tft->spiRead();
      green = (green >> 1) & 0b00111111; // need bits xGGGGGGx
      // Serial.print("Green: "); Serial.println(green,BIN);
      byte blue = tft->spiRead();
      blue = (blue >> 2) & 0b00011111; // need bits xBBBBBxx
      // Serial.print("Blue:  "); Serial.println(blue,BIN);
      int16_t RGB = 0; // need to combine to RRRRRGGGGGGBBBBB
      RGB |= (uint16_t)red << 11;
      RGB |= (uint16_t)green << 5;
      RGB |= (uint16_t)blue;
      // Serial.print("RGB:   "); Serial.println((uint16_t)combined,HEX);
      canvas->drawPixel(x+c,y+r,(uint16_t)RGB);
    }
  }
  tft->endWrite();
}