如何在文档目录中将UIImage保存为BMP文件 [英] How do i save an UIImage as a BMP file in documents directory

查看:163
本文介绍了如何在文档目录中将UIImage保存为BMP文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有人问过类似的问题,但它们始终包含答案使用UIImagePNGRepresentation或UIImageJPEGRepresentation",但这对我不起作用,因为我必须将此文件发送到仅接受BMP图像的外部Web服务.

Similar questions has been asked but they always contain the answer "use UIImagePNGRepresentation or UIImageJPEGRepresentation" But that wont work for me since i have to send this file to an external webservice that only accepts BMP images.

这是我到目前为止已经实现的

This is what i have implemented so far

-(NSData*)getBitmapRepresentationFromUIImage:(UIImage*)img{

CGImageRef cgiImg =[img CGImage];
CGColorSpaceRef colorSpaceRef = CGImageGetColorSpace(cgiImg);    

size_t bitsPerComponent = CGImageGetBitsPerComponent(cgiImg);
size_t bytesPerRow      = CGImageGetBytesPerRow(cgiImg);
size_t dataSize         = bytesPerRow * CGImageGetHeight(cgiImg);

void* imgBuf = malloc(dataSize);

CGContextRef bmpContext = CGBitmapContextCreate(imgBuf,
                                                   CGImageGetWidth(cgiImg),
                                                   CGImageGetHeight(cgiImg),
                                                   bitsPerComponent,
                                                   bytesPerRow,
                                                   colorSpaceRef,
                                                   kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big);


CGContextDrawImage(bmpContext, CGRectMake(0, 0, CGImageGetWidth(cgiImg), CGImageGetHeight(cgiImg)), cgiImg);

NSData* dataToReturn  = nil; 




if (imgBuf!=NULL) {

    dataToReturn = [[NSData alloc] initWithBytes:imgBuf length:dataSize];
    free(imgBuf);
    /*debug*/
    [self saveNSDataAsBitmap:dataToReturn fileName:@"signature"];
    /**/
}



return  dataToReturn;


}

-(void)saveNSDataAsBitmap:(NSData*)data fileName:(NSString*)name{    

NSString* fileName = [NSString stringWithFormat:@"%@%@",name,@".bmp"];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];    
NSString *completePath = [documentsDirectory stringByAppendingPathComponent:fileName];    
[data writeToFile:completePath atomically:YES];    
}

这会将文件保存到文档目录,但是我无法通过预览打开该文件.

This saves a file to the documents directory but i cant open that file with preview.

我在做什么错?有没有更简单的方法?

What am i doing wrong ? is there an easier way ?

编辑

我现在为文件头添加了结构

I have now added structs for the file header

#pragma pack(1)
typedef struct 
{
    UInt16 magic;  //specifies the file type "BM" 0x424d
    UInt32 bfSize;  //specifies the size in bytes of the bitmap file
    UInt16 bfReserved1;  //reserved; must be 0
    UInt16 bfReserved2;  //reserved; must be 0
    UInt32 bOffBits;  
} BmpFileHeaderStruct, *BmpFileHeaderStructRef;
#pragma pack(0)

#pragma pack(1)
typedef struct
{   UInt32 biSize;
    int32_t  biWidth;
    int32_t  biHeight;
    UInt16  biPlanes;
    UInt16  biBitCount;
    UInt32 biCompression;
    UInt32 biSizeImage;
    int32_t  biXPelsPerMeter;
    int32_t  biYPelsPerMeter;
    UInt32 biClrUsed;
    UInt32 biClrImportant;
} BmpFileInfoStruct,*BmpFileInfoStructRef;
#pragma pack(0)

我还实现了一个将标题附加到imgBuf开头的功能

I have also implemented a function to attatch a header to the start of imgBuf

-(void*)attatchBmpFileHeaderFor:(void*)imgBuf sizeOfBuff:(size_t)buffSize forImage:(CGImageRef)img{

BmpFileHeaderStruct headerStruct = {0};
headerStruct.magic = 0x424d;
headerStruct.bfSize = buffSize;
headerStruct.bOffBits = (sizeof(BmpFileHeaderStruct)*8) + (sizeof(BmpFileInfoStruct)*8);//hmmm ? 



BmpFileInfoStruct infoStruct = {0};
infoStruct.biSize = sizeof(BmpFileInfoStruct);
infoStruct.biWidth = CGImageGetWidth(img);
infoStruct.biHeight = CGImageGetHeight(img);
infoStruct.biPlanes = 1;
infoStruct.biBitCount = CGImageGetBitsPerPixel(img);
infoStruct.biSizeImage = buffSize;

void * fileBmpBuf = malloc(sizeof(BmpFileInfoStruct)+sizeof(BmpFileHeaderStruct)+sizeof(buffSize));

void *pIter = fileBmpBuf;
memcpy(pIter, &headerStruct, sizeof(BmpFileHeaderStruct));
pIter += sizeof(BmpFileHeaderStruct);
memcpy(pIter, &infoStruct, sizeof(BmpFileInfoStruct));
pIter += sizeof(BmpFileInfoStruct);
memcpy(pIter, imgBuf, buffSize);

return fileBmpBuf;    
}

这不起作用,有时由于崩溃的错误指针未分配到最后一个memcpy调用而崩溃,这很奇怪,因为我当时实际上并未释放任何数据.当它工作时,它会生成一个无法读取的文件.
我是否必须改为实现bitmapv5header结构?在哪里可以找到有关如何用值填充此结构的文档?

This does not work , sometimes it crashes due to the error pointer being freed was not allocated on the last memcpy call which is weird since i dont actually free any data at that point. When it works it produces a file that cant be read.
Do i have to implement a bitmapv5header structure instead ? Where can i find documentation on how i should fill this struct with values ?

推荐答案

您不能只保存添加特定标题和调色板所必需的数据. 看一下文件格式: http://en.wikipedia.org/wiki/BMP_file_format

you can't just save the data you have to add a specific header and the palette. Take a look at the file format: http://en.wikipedia.org/wiki/BMP_file_format

这篇关于如何在文档目录中将UIImage保存为BMP文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆