Go Down

Topic: Copying a JPEG Image using a uint8_t array to the same SD where original is (Read 174 times) previous topic - next topic

ScorchedCircuit

I hope this is the right place to post this. My objective with the following code is pretty simple. I have a JPEG image on my SD and want to create a duplicate using arduino. I'm not looking into transmitting it, or anything fancy. Just a boring copy inside the same SD.

This is the strategy of my code:

I open it, read it, and store each byte inside the array 'a'

I create a new file, open, and write in it, byte by byte in the same order, what was stored inside the array.

I've gone through enough trial and error to understand this doesn't work. Despite having bytes written in the exact same order, there's a crucial piece of information i'm missing. I've gone around the web, but i haven't found anything specific on what inside a JPEG other than a header and a tail, both which i'm sure were copied faithfully.

When I copied both files to my computer, I noticed some differences on the ASCII code when inspecting them with notepad, despite the arduino printing the exact same bytes. Another difference is that the original JPEG has code written in different lines, while my copy has all the bytes written in one line. This comes off quite confusingly to me, since the original picture was created in a similar process with the adafruit camera library:

Code: [Select]
  uint16_t jpglen = cam.frameLength();
  Serial.print("Storing ");
  Serial.print(jpglen, DEC);
  Serial.println(" byte image.");
  uint8_t a[jpglen];

  int32_t time = millis();
  pinMode(8, OUTPUT); //why 8? why do we need to have an output?
  // Read all the data up to # bytes!
  int innerCount = 0; // For counting # of writes inside array a
  int wCount = 0; // For counting number of writes for normal operation
  while (jpglen > 0) {
    // read 32 bytes at a time;
    uint8_t *buffer;
    uint8_t bytesToRead = min(32, jpglen); // change 32 to 64 for a speedup but may not work with all setups!
    buffer = cam.readPicture(bytesToRead);
    imgFile.write(buffer, bytesToRead);


As you can see (or correct me if I'm wrong), the function above works by creating a buffer and copying 32 bytes at a time. I was aiming to replicate this process:

First the code for the array:

Code: [Select]
    File ImgtoCopy = SD.open(filename, FILE_READ); // We are reading the file this time, not opening
    uint16_t photosize = ImgtoCopy.size(); //must be uint16 to hold entire value
    Serial.print("Photosize: ");
    Serial.println(photosize, DEC);   
    Serial.println("Starting Segmentation");
//    int photosizeDEC;
//    photosizeDEC = (int)photosize;
//    int l1 = 19200; //bytes must be divisible by 32 on first two packs
//    int l2 = 19200;
//    int l3 = photosizeDEC - 38400;
    uint8_t a[photosize];

    for (int i = 0; i < photosize; i++){
      a[i] = (uint8_t)ImgtoCopy.read();
      Serial.print(a[i]);
      Serial.print(",");
      if (i%128 == 0 && i != 0){ // a dot every 128 loops
        Serial.println(".");
      }
    }



And now the code for copying the insides of the array into a new file:


Code: [Select]
  File copy = SD.open(filename3, FILE_WRITE); //Create and open Image File //this is not being executed
  uint16_t photosize2 = sizeof(a); //should be equal to the first hptosize
  Serial.print("Size of a in bytes: ");
  Serial.println(photosize2);
  uint16_t jpglen2 = photosize2;
  Serial.print("jpglen2 = ");
  Serial.println(jpglen2); 
  pinMode(8, OUTPUT);
  int x = 0;

//  for (int x= 0; x < DLSize*16; x++){
  while (jpglen2 > 0){
    uint8_t bytestoRead2 = min(32, jpglen2);
     Serial.print("Copying "); Serial.println(bytestoRead2);
    // read 32 byte at a time;
    copy.write(a, bytestoRead2);
    x+=bytestoRead2;
    if(x%photosize2 == 0 && x != 0) { // Every 32, give a little feedback so it doesn't appear locked up
      Serial.println("All bytes read!");
    }

    jpglen2 -= bytestoRead2;
  }




Follows my questions/thought on why I'm failing:

1. Do you know where I can find relevant information about JPEGs relevant for this method?
2. Is this approach even feasible?
3. Is my problem located on me misunderstanding the exact functioning of the function .write inside the SD and cam.readPicture from the adafruit camera library on the first code block?
4. Do you suspect that for the first atch of code to work, while the others don't, means the cam.readPicture does more than simply give the bytes in the right order?
5. Which part of my output would you like to see?

Follows attached the original, A0004, and the copy, B0000. Open with notepad to check the ASCII if you feel like it.


Thank you for your time,
SC

christop

Code: [Select]

copy.write(a, bytestoRead2);


This line is writing the same 32 bytes to the file each time. You need to use a+x to read from offsets 0, 32, 64, etc. into the array.

Go Up