加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

iphone – 从PDF中提取图像

发布时间:2020-12-14 17:17:24 所属栏目:百科 来源:网络整理
导读:我有一些关于从iPhone应用程序中提供的PDF文档中专门提取图像(仅图像)的疑问. 我已经浏览了苹果的文档 – 但我没有找到它. 我已经完成了从PDF文档获取图像的努力. -(IBAction)btnTappedImages:(id)sender{ // MyGetPDFDocumentRef is custom c method // fil
我有一些关于从iPhone应用程序中提供的PDF文档中专门提取图像(仅图像)的疑问.

我已经浏览了苹果的文档 – 但我没有找到它.

我已经完成了从PDF文档获取图像的努力.

-(IBAction)btnTappedImages:(id)sender{

    // MyGetPDFDocumentRef is custom c method 
    // & filePath is path to pdf document.
    CGPDFDocumentRef document = MyGetPDFDocumentRef ([filePath UTF8String]);

    int pgcnt = CGPDFDocumentGetNumberOfPages( document );

    for( int i1 = 0; i1 < pgcnt; ++i1 ) {
        // 1. Open Document page 
        CGPDFPageRef pg = CGPDFDocumentGetPage (document,i1+1);
        if( !pg ) {
            NSLog(@"Couldn't open page.");
        }
        // 2. get page dictionary
        CGPDFDictionaryRef dict = CGPDFPageGetDictionary( pg );
        if( !dict ) {
            NSLog(@"Couldn't open page dictionary.");
        }
        // 3. get page contents stream
        CGPDFStreamRef cont;
        if( !CGPDFDictionaryGetStream( dict,"Contents",&cont ) ) {
            NSLog(@"Couldn't open page stream.");
        }
        // 4. copy page contents steam
        //  CFDataRef contdata = CGPDFStreamCopyData( cont,NULL );

        // 5. get the media array from stream
        CGPDFArrayRef media;
        if( !CGPDFDictionaryGetArray( dict,"MediaBox",&media ) ) {
            NSLog(@"Couldn't open page Media.");
        }

        // 6. open media & get it's size
        CGPDFInteger mediatop,medialeft;
        CGPDFReal mediaright,mediabottom;
        if( !CGPDFArrayGetInteger( media,&mediatop ) || !CGPDFArrayGetInteger( media,1,&medialeft ) || !CGPDFArrayGetNumber( media,2,&mediaright ) || !CGPDFArrayGetNumber( media,3,&mediabottom ) ) {
            NSLog(@"Couldn't open page Media Box.");
        }

        // 7. set media size 
        double mediawidth = mediaright - medialeft,mediaheight = mediabottom - mediatop;

        // 8. get media resources
        CGPDFDictionaryRef res;
        if( !CGPDFDictionaryGetDictionary( dict,"Resources",&res ) ) {
            NSLog(@"Couldn't Open Page Media Reopsources.");
        }

        // 9. get xObject from media resources  
        CGPDFDictionaryRef xobj;
        if( !CGPDFDictionaryGetDictionary( res,"XObject",&xobj ) ) {
            NSLog(@"Couldn't load page Xobjects.");
        }

        char imagestr[16];
        sprintf( imagestr,"Im%d",i1 );

        // 10. get x object stream
        CGPDFStreamRef strm;
        if( !CGPDFDictionaryGetStream( xobj,imagestr,&strm ) ) {
            NSLog(@"Couldn't load stream for xObject");
        }

        // 11. get dictionary from xObject Stream
        CGPDFDictionaryRef strmdict = CGPDFStreamGetDictionary( strm );
        if( !strmdict ) {
            NSLog(@"Failed to load dictionary for xObject");
        }

        // 12. get type of xObject
        const char * type;
        if( !CGPDFDictionaryGetName( strmdict,"Type",&type ) || strcmp(type,"XObject" ) ) {
            NSLog(@"Couldn't load xObject Type");
        }

        // 13. Check weather subtype is image or not
        const char * subtype;
        if( !CGPDFDictionaryGetName( strmdict,"Subtype",&subtype ) || strcmp( subtype,"Image" ) ) {
            NSLog(@"xObject is not image");
        }

        // 14. Bits per component
        CGPDFInteger bitsper;
        if( !CGPDFDictionaryGetInteger( strmdict,"BitsPerComponent",&bitsper ) || bitsper != 1 ) {
            NSLog(@"Bits per component not loaded");
        }

        // 15. Type of filter of image
        const char * filter;
        if( !CGPDFDictionaryGetName( strmdict,"Filter",&filter ) || strcmp( filter,"FlateDecode" ) ) {
            NSLog(@"Filter not loaded");
        }

        // 16. Image height width   
        CGPDFInteger width,height;
        if( !CGPDFDictionaryGetInteger( strmdict,"Width",&width ) || !CGPDFDictionaryGetInteger( strmdict,"Height",&height ) ) {
            NSLog(@"Image Height - width not loaded.");
        }

        // 17. Load image bytes & verify it
        CGPDFDataFormat fmt = CGPDFDataFormatRaw;
        CFDataRef data = CGPDFStreamCopyData( strm,&fmt );

        int32_t len = CFDataGetLength( data );
        const void * bytes = CFDataGetBytePtr( data );

        // now I have bytes for images in "bytes" pointer the problem is how to covert it into UIImage

        NSLog(@"Image bytes length - %i",len);  
        int32_t rowbytes = (width + 7) / 8;
        if( rowbytes * height != len ) {
            NSLog(@"Invalid Image");
        }

        double xres = width / mediawidth * 72.0,yres = height / mediaheight * 72.0;
        xres = round( xres * 1000 ) / 1000;
        yres = round( yres * 1000 ) / 1000;
    }
}

解决方法

是的!我找到了.但它看起来非常可怕 – 巨大的代码.

NSMutableArray *aRefImgs;
void setRefImgs(NSMutableArray *ref){
    aRefImgs=ref;
}

NSMutableArray* ImgArrRef(){
    return aRefImgs;
}

CGPDFDocumentRef MyGetPDFDocumentRef (const char *filename) {
    CFStringRef path;
    CFURLRef url;
    CGPDFDocumentRef document;
    path = CFStringCreateWithCString (NULL,filename,kCFStringEncodingUTF8);
    url = CFURLCreateWithFileSystemPath (NULL,path,kCFURLPOSIXPathStyle,0);
    CFRelease (path);
    document = CGPDFDocumentCreateWithURL (url);// 2
    CFRelease(url);
    int count = CGPDFDocumentGetNumberOfPages (document);// 3
    if (count == 0) {
        printf("`%s' needs at least one page!",filename);
        return NULL;
    }
    return document;
}


CGFloat *decodeValuesFromImageDictionary(CGPDFDictionaryRef dict,CGColorSpaceRef cgColorSpace,NSInteger bitsPerComponent) {
    CGFloat *decodeValues = NULL;
    CGPDFArrayRef decodeArray = NULL;

    if (CGPDFDictionaryGetArray(dict,"Decode",&decodeArray)) {
        size_t count = CGPDFArrayGetCount(decodeArray);
        decodeValues = malloc(sizeof(CGFloat) * count);
        CGPDFReal realValue;
        int i;
        for (i = 0; i < count; i++) {
            CGPDFArrayGetNumber(decodeArray,i,&realValue);
            decodeValues[i] = realValue;
        }
    } else {
        size_t n;
        switch (CGColorSpaceGetModel(cgColorSpace)) {
            case kCGColorSpaceModelMonochrome:
                decodeValues = malloc(sizeof(CGFloat) * 2);
                decodeValues[0] = 0.0;
                decodeValues[1] = 1.0;
                break;
            case kCGColorSpaceModelRGB:
                decodeValues = malloc(sizeof(CGFloat) * 6);
                for (int i = 0; i < 6; i++) {
                    decodeValues[i] = i % 2 == 0 ? 0 : 1;
                }
                break;
            case kCGColorSpaceModelCMYK:
                decodeValues = malloc(sizeof(CGFloat) * 8);
                for (int i = 0; i < 8; i++) {
                    decodeValues[i] = i % 2 == 0 ? 0.0 :
                    1.0;
                }
                break;
            case kCGColorSpaceModelLab:
                // ????
                break;
            case kCGColorSpaceModelDeviceN:
                n =
                CGColorSpaceGetNumberOfComponents(cgColorSpace) * 2;
                decodeValues = malloc(sizeof(CGFloat) * (n *
                                                         2));
                for (int i = 0; i < n; i++) {
                    decodeValues[i] = i % 2 == 0 ? 0.0 :
                    1.0;
                }
                break;
            case kCGColorSpaceModelIndexed:
                decodeValues = malloc(sizeof(CGFloat) * 2);
                decodeValues[0] = 0.0;
                decodeValues[1] = pow(2.0,(double)bitsPerComponent) - 1;
                break;
            default:
                break;
        }
    }

    return (CGFloat *)CFMakeCollectable(decodeValues);
}

UIImage *getImageRef(CGPDFStreamRef myStream) {
    CGPDFArrayRef colorSpaceArray = NULL;
    CGPDFStreamRef dataStream;
    CGPDFDataFormat format;
    CGPDFDictionaryRef dict;
    CGPDFInteger width,height,bps,spp;
    CGPDFBoolean interpolation = 0;
    //  NSString *colorSpace = nil;
    CGColorSpaceRef cgColorSpace;
    const char *name = NULL,*colorSpaceName = NULL,*renderingIntentName = NULL;
    CFDataRef imageDataPtr = NULL;
    CGImageRef cgImage;
    //maskImage = NULL,CGImageRef sourceImage = NULL;
    CGDataProviderRef dataProvider;
    CGColorRenderingIntent renderingIntent;
    CGFloat *decodeValues = NULL;
    UIImage *image;

    if (myStream == NULL)
        return nil;

    dataStream = myStream;
    dict = CGPDFStreamGetDictionary(dataStream);

    // obtain the basic image information
    if (!CGPDFDictionaryGetName(dict,&name))
        return nil;

    if (strcmp(name,"Image") != 0)
        return nil;

    if (!CGPDFDictionaryGetInteger(dict,&width))
        return nil;

    if (!CGPDFDictionaryGetInteger(dict,&height))
        return nil;

    if (!CGPDFDictionaryGetInteger(dict,&bps))
        return nil;

    if (!CGPDFDictionaryGetBoolean(dict,"Interpolate",&interpolation))
        interpolation = NO;

    if (!CGPDFDictionaryGetName(dict,"Intent",&renderingIntentName))
        renderingIntent = kCGRenderingIntentDefault;
    else{
        renderingIntent = kCGRenderingIntentDefault;
        //      renderingIntent = renderingIntentFromName(renderingIntentName);
    }

    imageDataPtr = CGPDFStreamCopyData(dataStream,&format);
    dataProvider = CGDataProviderCreateWithCFData(imageDataPtr);
    CFRelease(imageDataPtr);

    if (CGPDFDictionaryGetArray(dict,"ColorSpace",&colorSpaceArray)) {
        cgColorSpace = CGColorSpaceCreateDeviceRGB();
        //      cgColorSpace = colorSpaceFromPDFArray(colorSpaceArray);
        spp = CGColorSpaceGetNumberOfComponents(cgColorSpace);
    } else if (CGPDFDictionaryGetName(dict,&colorSpaceName)) {
        if (strcmp(colorSpaceName,"DeviceRGB") == 0) {
            cgColorSpace = CGColorSpaceCreateDeviceRGB();
            //          CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB);
            spp = 3;
        } else if (strcmp(colorSpaceName,"DeviceCMYK") == 0) {     
            cgColorSpace = CGColorSpaceCreateDeviceCMYK();
            //          CGColorSpaceCreateWithName(kCGColorSpaceGenericCMYK);
            spp = 4;
        } else if (strcmp(colorSpaceName,"DeviceGray") == 0) {
            cgColorSpace = CGColorSpaceCreateDeviceGray();
            //          CGColorSpaceCreateWithName(kCGColorSpaceGenericGray);
            spp = 1;
        } else if (bps == 1) { // if there's no colorspace entry,there's still one we can infer from bps
            cgColorSpace = CGColorSpaceCreateDeviceGray();
            //          colorSpace = NSDeviceBlackColorSpace;
            spp = 1;
        }
    }

    decodeValues = decodeValuesFromImageDictionary(dict,cgColorSpace,bps);

    int rowBits = bps * spp * width;
    int rowBytes = rowBits / 8;
    // pdf image row lengths are padded to byte-alignment
    if (rowBits % 8 != 0)
        ++rowBytes;

//  maskImage = SMaskImageFromImageDictionary(dict);

    if (format == CGPDFDataFormatRaw)
    {
        sourceImage = CGImageCreate(width,bps * spp,rowBytes,dataProvider,decodeValues,interpolation,renderingIntent);
        CGDataProviderRelease(dataProvider);
        cgImage = sourceImage;
//      if (maskImage != NULL) {
//          cgImage = CGImageCreateWithMask(sourceImage,maskImage);
//          CGImageRelease(sourceImage);
//          CGImageRelease(maskImage);
//      } else {
//          cgImage = sourceImage;
//      }
    } else {
        if (format == CGPDFDataFormatJPEGEncoded){ // JPEG data requires a CGImage; AppKit can't decode it {
            sourceImage =
            CGImageCreateWithJPEGDataProvider(dataProvider,renderingIntent);
            CGDataProviderRelease(dataProvider);
            cgImage = sourceImage;
//          if (maskImage != NULL) {
//              cgImage = CGImageCreateWithMask(sourceImage,maskImage);
//              CGImageRelease(sourceImage);
//              CGImageRelease(maskImage);
//          } else {
//              cgImage = sourceImage;
//          }
        }
        // note that we could have handled JPEG with ImageIO as well
        else if (format == CGPDFDataFormatJPEG2000) { // JPEG2000 requires ImageIO {
            CFDictionaryRef dictionary = CFDictionaryCreate(NULL,NULL,NULL);
            sourceImage=
            CGImageCreateWithJPEGDataProvider(dataProvider,renderingIntent);


            //          CGImageSourceRef cgImageSource = CGImageSourceCreateWithDataProvider(dataProvider,dictionary);
            CGDataProviderRelease(dataProvider);

            cgImage=sourceImage;

            //          cgImage = CGImageSourceCreateImageAtIndex(cgImageSource,dictionary);
            CFRelease(dictionary);
        } else // some format we don't know about or an error in the PDF
            return nil;
    }
    image=[UIImage imageWithCGImage:cgImage];   
    return image;
}

@implementation DashBoard

// Implement viewDidLoad to do additional setup after loading the view,typically from a nib.
- (void)viewDidLoad {
    [super viewDidLoad];
    filePath=[[NSString alloc] initWithString:[[NSBundle mainBundle] pathForResource:@"per" ofType:@"pdf"]];
}



-(IBAction)btnTappedText:(id)sender{
    if(arrImgs!=nil && [arrImgs retainCount]>0 ) { [arrImgs release]; arrImgs=nil; }
    arrImgs=[[NSMutableArray alloc] init];

    setRefImgs(arrImgs);
//  if(nxtTxtDtlVCtr!=nil && [nxtTxtDtlVCtr retainCount]>0) { [nxtTxtDtlVCtr release]; nxtTxtDtlVCtr=nil; }
//  nxtTxtDtlVCtr=[[TxtDtlVCtr alloc] initWithNibName:@"TxtDtlVCtr" bundle:nil];
//  nxtTxtDtlVCtr.str=StringRef();
//  [self.navigationController pushViewController:nxtTxtDtlVCtr animated:YES];

    // 1. Open Document page
    CGPDFDocumentRef document = MyGetPDFDocumentRef ([filePath UTF8String]);

    int pgcnt = CGPDFDocumentGetNumberOfPages( document );

    for( int i1 = 0; i1 < pgcnt; ++i1 ) {

        CGPDFPageRef pg = CGPDFDocumentGetPage (document,i1+1);
        if( !pg ) {
            NSLog(@"Couldn't open page.");
        } else {

            // 2. get page dictionary
            CGPDFDictionaryRef dict = CGPDFPageGetDictionary( pg );
            if( !dict ) {
                NSLog(@"Couldn't open page dictionary.");
            } else {
                // 3. get page contents stream
                CGPDFStreamRef cont;
                if( !CGPDFDictionaryGetStream( dict,&cont ) ) {
                    NSLog(@"Couldn't open page stream.");
                } else {
                    // 4. copy page contents steam
                    //  CFDataRef contdata = CGPDFStreamCopyData( cont,NULL );

                    // 5. get the media array from stream
                    CGPDFArrayRef media;
                    if( !CGPDFDictionaryGetArray( dict,&media ) ) {
                        NSLog(@"Couldn't open page Media.");
                    } else {
                        // 6. open media & get it's size
                        CGPDFInteger mediatop,medialeft;
                        CGPDFReal mediaright,mediabottom;
                        if( !CGPDFArrayGetInteger( media,&mediabottom ) ) {
                            NSLog(@"Couldn't open page Media Box.");
                        } else {
                            // 7. set media size 
                            //      double mediawidth = mediaright - medialeft,mediaheight = mediabottom - mediatop;
                            // 8. get media resources
                            CGPDFDictionaryRef res;
                            if( !CGPDFDictionaryGetDictionary( dict,&res ) ) {
                                NSLog(@"Couldn't Open Page Media Reopsources.");
                            } else {
                                // 9. get xObject from media resources  
                                CGPDFDictionaryRef xobj;
                                if( !CGPDFDictionaryGetDictionary( res,&xobj ) ) {
                                    NSLog(@"Couldn't load page Xobjects.");
                                } else {
                                    CGPDFDictionaryApplyFunction(xobj,pdfDictionaryFunction,NULL);
                                }
                            }
                        }
                    }
                }
            }
        }
    }

    NSLog(@"Total images are - %i",[arrImgs count]);

    if(nxtImgVCtr!=nil && [nxtImgVCtr retainCount]>0 ) { [nxtImgVCtr release]; nxtImgVCtr=nil; }
    nxtImgVCtr=[[ImgVCtr alloc] initWithNibName:@"ImgVCtr" bundle:nil];
    nxtImgVCtr.arrImg=arrImgs;
    [self.navigationController pushViewController:nxtImgVCtr animated:YES];
}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读