4

こんにちはスレッドを実行して、ファイルの現在ダウンロードされているサイズを確認したいと思います。

これは私が使用するものです

UIImage *image = [[UIImage alloc] initWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:@"http://lasp.colorado.edu/home/wp-content/uploads/2011/03/suncombo1.jpg"]]];

NSString *docDir = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];

NSString *jpegFilePath = [NSString stringWithFormat:@"%@/test.jpeg",docDir];
NSData *data2 = [NSData dataWithData:UIImageJPEGRepresentation(image, 1.0f)];//1.0f = 100% quality
[data2 writeToFile:jpegFilePath atomically:YES];
downloadStatus.text =[NSString stringWithFormat:@"size: %zd", malloc_size(data2)];

[image release];

また、malloc_size(data2)をimageに変更しようとしましたが、これも実際の結果ではありません。これにはスレッドがなく、ダウンロードプロセス中にチェックされないことはわかっていますが、ファイルサイズを確認するためにここで何を使用する必要がありますか?

4

3 に答える 3

5

いくつかの観察:

  1. あなたの質問は、のサイズを取得する試みNSDataが失敗したと推定しました。ではない。aのサイズを取得する正しい方法は、をNSData使用することですlength

  2. ただし、混乱は、外部で生成されたJPEGをラウンドトリップで取得するUIImageUIImageJPEGRepresentation、同じが生成されるという誤った仮定に起因しNSDataます。これは非常にありそうになかったでしょう。変更された可能性のあるさまざまなJPG設定が多すぎます(JPEG Wikipediaページを参照)。元のファイルがどの設定を使用したかは確かにわかりません。私はそれを知っているかUIImageUIImageJPEGRepresentationファイルの色空間を変更しました。私はそれが他の多くのこともしていると賭けたいと思います。

  3. したがって、結果は正しいです。元のファイルは2.6MBで、結果のファイルは4.5MBでした。compressionQualityを1.0から0.99に変更すると、結果のファイルはわずか1.4MBになります。ただし、元のファイルが必要な場合は、最初に保存してください(以下のように)。

画像ファイルをダウンロードして保存し、にロードし、UIImageを介して再抽出しUIImageJPEGRepresentation、画像の別のコピーを保存する次のコードについて考えてみます。

// let's make filenames where we'll store the files

NSString *documentsPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSString *suncomboOrig = [documentsPath stringByAppendingPathExtension:@"suncombo1-orig.jpg"];
NSString *suncomboReprocessed = [documentsPath stringByAppendingPathExtension:@"suncombo1-reprocessed.jpg"];

// let's download the original suncombo1.jpg and save it in Documents and display the size

NSURL *url = [NSURL URLWithString:@"http://lasp.colorado.edu/home/wp-content/uploads/2011/03/suncombo1.jpg"];
NSData *data = [NSData dataWithContentsOfURL:url];
NSLog(@"original = %d", [data length]);
[data writeToFile:suncomboOrig atomically:NO];

// let's load that into a UIImage

UIImage *image = [UIImage imageWithData:data];

// let's extract data out of the image and write that to Documents, too, also logging the size of that

NSData *data2 = UIImageJPEGRepresentation(image, 1.0);
NSLog(@"reprocessed = %d", [data2 length]);
[data2 writeToFile:suncomboReprocessed atomically:NO];

それは何を報告しますか:

2012-12-13 22:30:39.576 imageapp [90647:c07] original = 2569128
2012-12-13 22:30:40.141 imageapp [90647:c07]再処理= 4382876

したがって、最初に保存したファイル(サーバー上にあるものと同じだと思われます)は2.5 MBであり、へのラウンドトリップを実行した後のファイルは4.3MBをUIImage介して再抽出されました。上記のコードで保存された2つのファイルを見ると、これらのNSDataサイズが正しいことが確認できます。


私の最初の答えは、OPがのサイズを取得できなかったかNSData、単純な質問の根底にある微妙な問題(ダウンロードが開始される前にサイズを取得したいなど)があったという推定に基づいていました。とにかく、私は上記の答えを拡張しましたが、歴史的な目的のために元の答えを保持します:

元の回答:

NSDataプロパティは、lengthダウンロードされたバイト数を示します。例[data2 length]

それが本当に大きい場合は、NSURLConnection非同期でダウンロードするために使用できます。これは、Webサーバーによっては、メソッドでダウンロードが開始される前にdidReceiveResponse(パラメーターのexpectedContentLengthプロパティを使用して)合計ファイルサイズを提供する場合があります。NSHTTPURLResponse *response

ダウンロードのもう1つの優れた点NSURLConnectionは、ダウンロード時にファイル全体をメモリにロードする必要がなく、永続ストレージに直接ストリーミングできることです。これは、複数の大きなファイルをダウンロードする場合に特に便利です。同時に。適度なサイズのファイルをダウンロードする場合、NSURLConnectionダウンロードに使用するのはやり過ぎですが、大きなファイルをダウンロードするときに進行状況インジケーターが必要な場合(またはダウンロードを開始する前にファイルサイズを取得したい場合)に便利です。

ただし、にダウンロードされたバイト数を知りたいだけの場合はNSData、を使用してくださいlength

于 2012-12-14T01:04:43.603 に答える
4

CFILEクラスを使用してファイルサイズを取得できます。

 FILE * handle = fopen([jpegFilePath UTF8String], "r");
 fseek(handle, EOF); // seek to end of file
 int size = ftell(handle); // returns position in bytes
 fclose();
于 2012-12-14T01:04:30.147 に答える
3

「現在の」サイズと言ってスレッドについて言及しているので、受け取ったファイルサイズを決定しようとしていると思います。その場合、スレッドをから無料でNSURLConnection取得でき、受信したデリゲートメソッドからデータサイズを取得できます...

ダウンロードしたデータのインスタンス変数を作成します。

@property (nonatomic, strong) NSMutableData *data;

接続を作成して起動します。

NSURL *url = [NSURL URLWithString:@"http://lasp.colorado.edu/home/wp-content/uploads/2011/03/suncombo1.jpg"];
NSURLRequest *request = [NSURLRequest requestWithURL:url];

self.data = [NSMutableData data];
NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request delegate:self];

NSURLConnectionDataDelegateに必要なメソッドを実装します。あなたの質問のために、特別な部分はこれです:

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
    [self.data appendData:data];

    NSUInteger bytesSoFar = [self.data length];
    // you're on the app main thread here, so you can do something
    // to the UI to indicate progress
    downloadStatus.text = [NSString stringWithFormat@"size: %d", bytesSoFar];
}

プロトコルの残りの部分に関する優れたドキュメントはここにあります。dataWithContentsOfURL接続が完了すると、 ...で行ったようにイメージを作成できます。

- (void)connectionDidFinishLoading:(NSURLConnection *)connection {

    UIImage *image = [[UIImage alloc] initWithData:self.data];
    downloadStatus.text = [NSString stringWithFormat@"size: %d", [self.data length]];
}
于 2012-12-14T01:26:12.940 に答える