ios - 通过蓝牙 4.0 LE 发送图像文件

标签 ios objective-c bluetooth core-bluetooth

我正在尝试通过蓝牙 4.0 LE 将 .png 图像文件从一台 iOS 设备发送到另一台。

我能够处理像字符串这样的简单数据,但无法成功发送和使用图像文件。

在外围设备中,我从这个开始

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

然后我将 myData 设为特征值。

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

在中央设备中,当特征值更新时我有这个

- (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 }

编辑 8-27-13: 我能够成功发送一个单一颜色的 1by1 像素 .png 文件,该文件大约有 5,600 字节大。我无法发送只有大约 2,000 字节的多色 20by20pixel .png 文件。我能够发送仅包含一种颜色和较少像素的较大文件,但无法发送包含多种颜色和较多像素的较小文件。

编辑 8-30-13: 我必须将数据解析成更小的 block 。在 Apple 的一个示例项目中,我发现了一种方法可以做到这一点。我似乎无法确切地理解如何在我自己的代码中实现它,但我目前正在尝试弄清楚如何实现。这是代码:

- (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;
    }
}}

我的imageView是黑色方 block ,应该是显示我发过来的图片。 enter image description here

最佳答案

在 iOS 6 上,BLE 允许您发送大约 20 字节的数据 block 。有关如何分割要发送的数据以及如何使用基于通知的传输的示例,请下载 BTLE Transfer Apple Example application .

为了更好地了解您可以达到的速度,我建议您分析这张图 http://www.scriptreactor.com/conn_interval-throughput.pdf它显示了作为连接间隔函数的可实现速度。 iOS 不会为您提供如此细粒度的控制,但此信息对于您进行计算仍然很有值(value)。

关于ios - 通过蓝牙 4.0 LE 发送图像文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18476335/

相关文章:

objective-c - 如何将一个 NSMutablearray 复制到另一个 NSMutablearray?

objective-c - 重复更新 UIImage 未显示在屏幕上

iphone-sdk-3.0 - 如何测试iphone p2p应用程序?

使用(用户)杀死的应用程序进行 iOS BLE 扫描

java - Android - 如何监听蓝牙输出流被清空

ios - Objective-C iOS7检测事件的电话和麦克风可用性

iphone - NSMutableArray 属性 - 释放 child

iphone - 更改 iPhone 上的国家/地区以进行本地化测试

iphone - 用于 iOS 项目的 XMLRPC-iOS

ios - 随时间改变背景