■問題
iOSでisLoadingが常にYESを返す場合があり、完全にロードしたかどうかを判別できない場合があります。
■解決策
webViewDidFinishLoadが呼ばれた時点で、スクリーンショットを取り、白・黒の割合が90%未満だった場合にはロードされていると認識する。
※この方法では完全にとれない場合もあります。
※100%ロードしたものを表示したい場合には、timer等で以下の関数を処理を実行させて下さい。
■予備知識
UIViewからサムネイルを取得する方法
http://araking56.blog134.fc2.com/blog-entry-184.html
画像のピクセルから色を判別する方法
http://www.markj.net/iphone-uiimage-pixel-color/
■good
[objc]
– (void)webViewDidFinishLoad:(UIWebView *)webView {
BOOL isLoaded = [self isLoaded:webView];
if(isLoaded){
[self.imageView setHidden:NO];
}
}
-(BOOL)isLoaded:(UIWebView *)webView{
//画像を送る
CGRect screenRect = webView.frame;
UIGraphicsBeginImageContext(webView.frame.size);
CGContextRef ctx = UIGraphicsGetCurrentContext();
CGContextFillRect(ctx, screenRect);
[webView.layer renderInContext:ctx];
UIImage *screenImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
//画像の内容を解析する
float percentage = [self getPercentageOfWhiteInImage:screenImage];
if (percentage > 0.9) {
NSLog(@"ほぼ真っ白 or 真っ黒なのでロードされていない");
}else{
NSLog(@"色がついているのでロード済み");
}
}
-(float)getPercentageOfWhiteInImage:(UIImage *)image{
CGImageRef inImage = image.CGImage;
CGContextRef cgctx = [self createARGBBitmapContextFromImage:inImage];
if (cgctx == NULL) { return 1.0; /* error */ }
size_t w = CGImageGetWidth(inImage);
size_t h = CGImageGetHeight(inImage);
CGRect rect = {{0,0},{w,h}};
CGContextDrawImage(cgctx, rect, inImage);
int startW = 0;
int startH = 0;
unsigned char* data = CGBitmapContextGetData (cgctx);
float result1 = [self getPercentageOfWhiteInPix:startW startH:startH data:data w:w h:h];
float result2 = [self getPercentageOfWhiteInPix:w/2-_estimateLengthstartH:h/2-_estimateLengthdata:data w:w h:h];
float result3 = [self getPercentageOfWhiteInPix:w-_estimateLengthstartH:h-_estimateLengthdata:data w:w h:h];
// When finished, release the context
CGContextRelease(cgctx);
// Free image data memory for the context
if (data) { free(data); }
return (result1+result2+result3)/(float)3;
}
-(float)getPercentageOfWhiteInPix:(int)startW startH:(int)startH data:(unsigned char *)data w:(size_t)w h:(size_t)h{
// Now we can get a pointer to the image data associated with the bitmap
// context.
int whiteCounter =0;
int blackCounter = 0;
int notWhiteCounter = 0;
//unsigned char* data = CGBitmapContextGetData (cgctx);
for (int width =0; width < _estimateLength ; width++) {
for (int height=0;height < _estimateLength; height++) {
if (data != NULL) {
//offset locates the pixel in the data from x,y.
//4 for 4 bytes of data per pixel, w is width of one row of data.
int offset = 4*((w*round(startH+height))+round(startW+width));
int alpha = data[offset];
int red = data[offset+1];
int green = data[offset+2];
int blue = data[offset+3];
if (red == 255 && green == 255 && blue == 255) {
whiteCounter++;
}else if(red ==0 && green==0 && blue==0){
blackCounter++;
}else {
notWhiteCounter++;
}
NSLog(@"offset: %i colors: RGB A %i %i %i %i",offset,red,green,blue,alpha);
//color = [UIColor colorWithRed:(red/255.0f) green:(green/255.0f) blue:(blue/255.0f) alpha:(alpha/255.0f)];
}
}
}
//大きい方を返す
if (whiteCounter > blackCounter) {
return (float)whiteCounter/(float)(notWhiteCounter+whiteCounter+blackCounter);
}else {
return (float)blackCounter/(float)(notWhiteCounter+whiteCounter+blackCounter);
}
}
– (CGContextRef) createARGBBitmapContextFromImage:(CGImageRef) inImage {
CGContextRef context = NULL;
CGColorSpaceRef colorSpace;
void * bitmapData;
int bitmapByteCount;
int bitmapBytesPerRow;
size_t pixelsWide = CGImageGetWidth(inImage);
size_t pixelsHigh = CGImageGetHeight(inImage);
bitmapBytesPerRow = (pixelsWide * 4);
bitmapByteCount = (bitmapBytesPerRow * pixelsHigh);
colorSpace = CGColorSpaceCreateDeviceRGB();
if (colorSpace == NULL)
{
fprintf(stderr, "Error allocating color space\n");
return NULL;
}
bitmapData = malloc( bitmapByteCount );
if (bitmapData == NULL)
{
fprintf (stderr, "Memory not allocated!");
CGColorSpaceRelease( colorSpace );
return NULL;
}
context = CGBitmapContextCreate (bitmapData,
pixelsWide,
pixelsHigh,
8, // bits per component
bitmapBytesPerRow,
colorSpace,
kCGImageAlphaPremultipliedFirst);
if (context == NULL)
{
free (bitmapData);
fprintf (stderr, "Context not created!");
}
// Make sure and release colorspace before returning
CGColorSpaceRelease( colorSpace );
return context;
}
[/objc]
最近のコメント