Before and after the first slice treatment effect comparison:
Before processing:
After processing:
Recent project needs, the picture shows two states, one is the original color, the other is black and white, but for these two states our server-side only to provide us with a set of color pictures, our front-end needs to handle the picture according to the state, so I consulted Baidu, found the following method:
-(uiimage*) Grayscale: (uiimage*) animage type: (int) Type {
Cgimageref imageref = animage.cgimage;
size_t width = cgimagegetwidth (imageref);
size_t height = cgimagegetheight (imageref);
size_t bitspercomponent = cgimagegetbitspercomponent (imageref);
size_t bitsperpixel = Cgimagegetbitsperpixel (imageref);
size_t Bytesperrow = Cgimagegetbytesperrow (imageref);
Cgcolorspaceref colorspace = Cgimagegetcolorspace (imageref);
Cgbitmapinfo bitmapinfo = Cgimagegetbitmapinfo (imageref);
BOOL Shouldinterpolate = Cgimagegetshouldinterpolate (imageref);
Cgcolorrenderingintent Intent = cgimagegetrenderingintent (IMAGEREF);
Cgdataproviderref Dataprovider = Cgimagegetdataprovider (imageref);
Cfdataref data = Cgdataprovidercopydata (Dataprovider);
UInt8 *buffer = (uint8*) cfdatagetbyteptr (data);
Nsuinteger x, y;
for (y = 0; y < height; y++) {
for (x = 0; x < width, x + +) {
UInt8 *tmp;
TMP = buffer + y * bytesperrow + x * 4;
UInt8 Red,green,blue;
Red = * (tmp + 0);
Green = * (tmp + 1);
Blue = * (tmp + 2);
UInt8 brightness;
Switch (type) {
Case 1:
Brightness = (* red + + * Green + 151 * blue)/256;
* (tmp + 0) = brightness;
* (tmp + 1) = brightness;
* (tmp + 2) = brightness;
Break
Case 2:
* (tmp + 0) = red;
* (tmp + 1) = green * 0.7;
* (tmp + 2) = blue * 0.4;
Break
Case 3:
* (tmp + 0) = 255-red;
* (tmp + 1) = 255-green;
* (tmp + 2) = 255-blue;
Break
Default
* (tmp + 0) = red;
* (tmp + 1) = green;
* (tmp + 2) = blue;
Break
}
}
}
Cfdataref effecteddata = cfdatacreate (NULL, buffer, cfdatagetlength (data));
Cgdataproviderref Effecteddataprovider = Cgdataprovidercreatewithcfdata (Effecteddata);
Cgimageref effectedcgimage = Cgimagecreate (
width, height,
Bitspercomponent, BitsPerPixel, Bytesperrow,
ColorSpace, Bitmapinfo, Effecteddataprovider,
NULL, shouldinterpolate, intent);
UIImage *effectedimage = [[UIImage alloc] initwithcgimage:effectedcgimage];
Cgimagerelease (Effectedcgimage);
Cfrelease (Effecteddataprovider);
Cfrelease (Effecteddata);
Cfrelease (data);
return effectedimage;
}
Then I wrote a demo, with the local image did the next, indeed, is worthy of the great God wrote, although can not understand, but will be used on the line, and then copied to our project went, the general thing developed here should be the perfect end, but this is the calm before the arrival of trouble, Then the following error occurs when running in the project:
Access to bad memory, if for OC if this problem can find some ideas, but for C language treatment Such a problem is confused, do not know what caused the problem, so at that time this bug made me at a loss, do not know where to start. Then after I repeated the test, get the following rule:
1> This problem does not occur with local image processing
2> for the network picture is the application installation (install the emulator or the real machine), the first time to run to the place when this problem occurs, and then how to deal with this image will not be a problem.
Problem positioning: Finally, I put the problem point in the picture cache, I am through the sdwebimage to do the picture download and cache, through the view code found that sdwebimage after the download is done after the image cache is asynchronous, that is, the first time the picture is downloaded, the local is not cached, and The image processed is in memory, and then a bad memory access occurs when processing the picture. And in the second processing time before the picture has been cached to the local, so there is no problem. Although I do not know why this method of processing will not be cached to the local image processing would have bad memory access, but eventually the problem to the location.
Solution: After sdwebimage download the picture, first check whether there is a local image, if not, then download the picture synchronized to local, and then get the image from the local processing. Problem Solving!
The code is as follows:
[[Sdwebimagemanager Sharedmanager] Downloadimagewithurl:imageurl options:sdwebimageretryfailed progress:nil completed:^ (UIImage *image, Nserror *error, Sdimagecachetype CacheType, BOOL finished, Nsurl *imageurl) {
nsstring* key = [[Sdwebimagemanager Sharedmanager] cachekeyforurl:imageurl];
BOOL result = [[Sdimagecache Sharedimagecache] diskimageexistswithkey:key];
nsstring* ImagePath = [[Sdimagecache Sharedimagecache] defaultcachepathforkey:key];
if (!result) {
BOOL imageispng = Imagedatahaspngpreffixwithdata (nil);
nsdata* imageData = nil;
if (imageispng) {
ImageData = uiimagepngrepresentation (image);
}
else {
ImageData = uiimagejpegrepresentation (image, (cgfloat) 1.0);
}
nsfilemanager* _filemanager = [Nsfilemanager Defaultmanager];
if (imageData) {
if (![ _filemanager Fileexistsatpath:imagepath]) {
[_filemanager createdirectoryatpath:imagepath withintermediatedirectories:yes Attributes:nil Error:NULL];
}
[_filemanager Createfileatpath:imagepath contents:imagedata Attributes:nil];
}
}
nsdata* NewData = [NSData Datawithcontentsoffile:imagepath];
uiimage* newimage = [UIImage imagewithdata:newdata];
uiimage* grayimage = [self grayscale:newimage type:1];
Self.imageView.image = Grayimage;
}];
Black-and-white processing of web images by IOS