提问人:Cosworth66 提问时间:7/29/2020 最后编辑:Cosworth66 更新时间:7/29/2020 访问量:64
Objective-c UIImage 到 Greyscale Bitmap 转换函数中的内存泄漏
Memory leak in Objective-c UIImage to Greyscale Bitmap conversion function
问:
我正在尝试解决 iOS 应用程序的内存泄漏问题,我已将其缩小到将 UIImage 转换为灰度位图的函数。代码工作正常,但每次运行会占用大约 500kb。
我有一种感觉,这是由 CGImageRef 和 CGDataRef 未释放引起的,但是如果我在函数结束时使用 CGImageRelease(sourceImage) 或 CGDataRelease(theData) 释放它们中的任何一个,那么返回的图像 grayBitmapImage 是空的。
谁能帮助我理解为什么我不能在不丢失最终图像的情况下发布这些 Refs 中的任何一个?
当我返回由 bytes[] 缓冲区创建的 grayBitmapImage 时,它们不应该已经用完并完成吗?
有谁看到此功能还有什么地方可能导致内存泄漏?
+ (NSData*) convertJpegToBmpGray: (UIImage *)houghSourceImage :(NSString *)destImgPath :(NSString *)fileName :(int)width : (int)height
{
RGBQUAD Palette[0x100];
int totalbytesinbitmap = (int)(width * height) + 54 + (0x100 * sizeof(RGBQUAD) + 2); //THE SIZE OF THE IMAGE WE WANT WITH NULL TERM
//OUTPUT IMAGE BUFFER
unsigned char *bytes = new unsigned char[totalbytesinbitmap];
[self writeBitmapHeaderGray:bytes :width :height];
UIImage *sourceImage1 = houghSourceImage;
if(sourceImage1==nil)
return nil;
CGImageRef sourceImage = sourceImage1.CGImage;
CFDataRef theData;
theData = CGDataProviderCopyData(CGImageGetDataProvider(sourceImage));
UInt8 *pixelDataS = (UInt8 *) CFDataGetBytePtr(theData);
int dataLength = (int)CFDataGetLength(theData); //LENGTH OF THE WHOLE BITMAP BUFFER
int row = (int)height -1; //NUMBER OF ROWS IS THE HEIGHT MINUS 1
int col = 0;
int totalbytesinrow = (int) width;
for(int i=0; i<dataLength;){
int red = pixelDataS[i++]; //GET RED PIXEL
int green = pixelDataS[i++]; //GET GREEN PIXEL
int blue = pixelDataS[i++]; //GET BLUE PIXEL
i++; //ADD A BYTE FOR RESERVED
if(col == totalbytesinrow){
col = 0; //RESET COLUMN COUNT TO ZERO AT END OF ROW
row--; //FIGURE OUT THE ROW AND COLUMN COUNTS
}
//STARTS THE LOCATION FROM THE END OF THE BUFFER AND WORKS BACKWARDS IN ROWS
int location = (row * totalbytesinrow) + col + 54 + (0x100 * sizeof(RGBQUAD));
//CONVERT ALL PIXELS TO GRAY
int gray = (red + green + blue) / 3;
bytes[location] = gray;
col++;
}
for(int i=0; i<0x100; i++) //CREATE THE PALETTE ARRAY FOR USE WITH GREYSCALE BITMAPS
{
Palette[i].rgbRed = i;
Palette[i].rgbGreen = i;
Palette[i].rgbBlue = i;
Palette[i].rgbReserved = 0;
}
int paletteLocation = 54; //START THE PALETTE RIGHT AFTER THE INFOHEADER
for(int i=0; i < 0x100; i++) //COPY THE PALETTE ARRAY INTO THE BYTE ARRAY AFTER INFOHEADER
{
bytes[paletteLocation] = Palette[i].rgbRed;
paletteLocation++;
bytes[paletteLocation] = Palette[i].rgbGreen;
paletteLocation++;
bytes[paletteLocation] = Palette[i].rgbBlue;
paletteLocation++;
bytes[paletteLocation] = Palette[i].rgbReserved;
paletteLocation++;
}
//ADD NULL TERMINATORS TO BITMAP BUFFER
bytes[totalbytesinbitmap+1] = 0x00;
bytes[totalbytesinbitmap+2] = 0x00;
NSData *grayBitmapImage = [NSData dataWithBytes:bytes length:totalbytesinbitmap];
CFAutorelease(theData); //EDIT-MEMORY LEAK FIXED BY ADDING THIS
delete[] bytes;
return grayBitmapImage;
}
该函数是这样调用的。
UIImage *image = [ImageUtils UIImageFromCVMat:small];
int width = image.size.width;
int height = image.size.height;
NSData *raw2dmiImage = [ImageUtils convertJpegToBmpGray :image :savedFilePath :@"raw2dmiImage.BMP" :width :height];
答: 暂无答案
评论
theData
CGDataProviderCopyData
CFAutorelease
sourceImage1
nil
bytes
CFRelease
theData