2013-08-27 22 views
13

Próbuję wysłać plik obrazu .png z jednego urządzenia iOS do innego przez Bluetooth 4.0 LE.Wysyłanie pliku obrazu przez Bluetooth 4.0 LE

Potrafię tworzyć proste elementy danych, takie jak ciągi, ale nie można pomyślnie wysyłać i wykorzystywać plików obrazów.

W urządzeniem peryferyjnym, zaczynam się z tym

pictureBeforeData = [UIImage imageNamed:@"myImage.png"]; 
NSData *myData = UIImagePNGRepresentation(pictureBeforeData); 

Potem robię myData wartości charakterystycznej za.

_myCharacteristic = 
[[CBMutableCharacteristic alloc] initWithType:_myCharacteristicUUID 
            properties:CBCharacteristicPropertyRead 
             value:myData 
            permissions:CBAttributePermissionsReadable]; 

W centralnego urządzenia, mam to kiedy wartość charakterystycznej jest aktualizowany

- (void)peripheral:(CBPeripheral *)peripheral didUpdateValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error { 
    if ([characteristic.UUID isEqual:[CBUUID UUIDWithString:_myCharacteristicUUID]]) { 
    NSLog(@"PICTURE CHARACTERISTIC FOUND"); // This successfully gets logged 

    NSData *dataFromCharacteristic = [[NSData alloc] initWithData:characteristic.value]; 

    UIImage *imageFromData = [[UIImage alloc]initWithData:dataFromCharacteristic]; 

    // This correctly logs the size of my image 
    NSLog(@"SIZE: %f, %f", imageFromData.size.height, imageFromData.size.width); 

    // This causes the imageView to turn completely black 
    _sentPictureImageView.image = imageFromData; 

    if (!([_myImagesArray containsObject:imageFromData])) 
    { 
     NSLog(@"DOES NOT CONTAIN"); // This is successfully logged 
     [_myImagesArray addObject:imageFromData]; // This runs but is apparently not adding the image to the array 
    } 

    NSLog(@"COUNT: %u", _contactsImagesArray.count); // This always logs 0 - The array is empty } 

EDIT 27.08.13: Jestem w stanie wysłać w ciągu jednego koloru 1by1 piksel Plik .png powodzeniem ma rozmiar około 5600 bajtów. Nie mogę wysłać wielobarwnego pliku .png o rozdzielczości 20 x 20 pikseli, który ma tylko około 2000 bajtów. Jestem w stanie przesłać większy plik, który zawiera tylko jeden kolor i mniej pikseli, ale nie można wysłać mniejszego pliku zawierającego wiele kolorów i więcej pikseli.

EDYCJA 8-30-13: Zdecydowanie muszę przeanalizować dane na mniejsze fragmenty. W jednym z przykładowych projektów Apple znalazłem metodę, która właśnie to robi. Nie mogę zrozumieć, jak dokładnie to zaimplementować we własnym kodzie, ale obecnie próbuję dowiedzieć się, jak to zrobić. Oto kod:

- (void)sendData { 
// First up, check if we're meant to be sending an EOM 
static BOOL sendingEOM = NO; 

if (sendingEOM) { 

    // send it 
    BOOL didSend = [self.peripheralManager updateValue:[@"EOM" dataUsingEncoding:NSUTF8StringEncoding] forCharacteristic:self.transferCharacteristic onSubscribedCentrals:nil]; 

    // Did it send? 
    if (didSend) { 

     // It did, so mark it as sent 
     sendingEOM = NO; 

     NSLog(@"Sent: EOM"); 
    } 

    // It didn't send, so we'll exit and wait for peripheralManagerIsReadyToUpdateSubscribers to call sendData again 
    return; 
} 

// We're not sending an EOM, so we're sending data 

// Is there any left to send? 

if (self.sendDataIndex >= self.dataToSend.length) { 

    // No data left. Do nothing 
    return; 
} 

// There's data left, so send until the callback fails, or we're done. 

BOOL didSend = YES; 

while (didSend) { 

    // Make the next chunk 

    // Work out how big it should be 
    NSInteger amountToSend = self.dataToSend.length - self.sendDataIndex; 

    // Can't be longer than 20 bytes 
    if (amountToSend > NOTIFY_MTU) amountToSend = NOTIFY_MTU; 

    // Copy out the data we want 
    NSData *chunk = [NSData dataWithBytes:self.dataToSend.bytes+self.sendDataIndex length:amountToSend]; 

    // Send it 
    didSend = [self.peripheralManager updateValue:chunk forCharacteristic:self.transferCharacteristic onSubscribedCentrals:nil]; 

    // If it didn't work, drop out and wait for the callback 
    if (!didSend) { 
     return; 
    } 

    NSString *stringFromData = [[NSString alloc] initWithData:chunk encoding:NSUTF8StringEncoding]; 
    NSLog(@"Sent: %@", stringFromData); 

    // It did send, so update our index 
    self.sendDataIndex += amountToSend; 

    // Was it the last one? 
    if (self.sendDataIndex >= self.dataToSend.length) { 

     // It was - send an EOM 

     // Set this so if the send fails, we'll send it next time 
     sendingEOM = YES; 

     // Send it 
     BOOL eomSent = [self.peripheralManager updateValue:[@"EOM" dataUsingEncoding:NSUTF8StringEncoding] forCharacteristic:self.transferCharacteristic onSubscribedCentrals:nil]; 

     if (eomSent) { 
      // It sent, we're all done 
      sendingEOM = NO; 

      NSLog(@"Sent: EOM"); 
     } 

     return; 
    } 
}} 

My imageView jest czarny kwadrat, który powinien być wyświetlany będzie obraz Wysłałem ponad. enter image description here

+0

Czy udało Ci się wysłać obraz za pomocą tego? – hmlasnk

Odpowiedz

2

BŁĄD jest znacząco ograniczony pod względem ilości danych, które można przesłać zarówno w charakterystyce, jak i w dowolnym pakiecie danych. Powinieneś nawiązać połączenie między urządzeniami, a następnie podzielić dane obrazu i wysyłać wiele małych pakietów. Filmy z WWDC 2013 zapewnią dobry przegląd i próbki kodu.

+0

Dzięki @Wain. Oglądałem filmy WWDC 2013 i dokładnie skanowałem plik pdf prezentacji CoreBluetooth. Nie mogę również znaleźć żadnych przykładowych projektów, które stanowią przykład dzielenia danych (najlepiej plików graficznych) na fragmenty, aby wysłać BTLE. – tagabek

+0

Film pokazuje dane kontaktowe, które są dzielone na pakiety i wysyłane. Myślę, że to było drugie wideo BT. Nie obraz, ale ta sama zasada obowiązuje. – Wain

+0

Znalazłem fragment kodu, który dzieli dane i nadal próbuję dowiedzieć się, jak zaimplementować je w moim projekcie. Edytowałem oryginalny wpis. – tagabek

11

W systemie iOS 6 BLE umożliwia wysyłanie około 20 bajtowych porcji danych. Aby zapoznać się z przykładem, w jaki sposób można podzielić dane, które mają zostać wysłane, oraz jak korzystać z transmisji opartej na powiadomieniach, pobierz numer BTLE Transfer Apple Example application.

Aby lepiej zrozumieć, jakie prędkości można osiągnąć, sugeruję przeanalizowanie tego diagramu. http://www.scriptreactor.com/conn_interval-throughput.pdf Przedstawia osiągalne prędkości jako funkcję interwału połączenia. System iOS nie zapewnia tak dokładnego sterowania, ale informacje te są nadal przydatne do obliczenia.

+0

Dzięki za odpowiedź. Użyłem aplikacji BTLE Transfer Example jako podstawy dla funkcjonalności BTLE mojej aplikacji. Znalazłem metodę '- (void) sendData' i zaczynam rozumieć, co dokładnie muszę zrobić. Dzięki. – tagabek

+2

@tagabek zrobił to lub inne rozwiązanie rozwiązać swój problem? W przypadku odpowiedzi na pytanie prawidłowe rozwiązanie powinno zostać zaakceptowane. Możesz to zrobić za pomocą znacznika wyboru przy odpowiedzi. – allprog

+1

@allprog - czy są jakieś nowe informacje o rozmiarze fragmentów, które możesz wysyłać w iOS7? Nigdzie nie mogłem znaleźć udokumentowanego ograniczenia tej wielkości ... – Gal

Powiązane problemy