日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

iOS中的图像处理(一)——基础滤镜

發布時間:2023/12/31 编程问答 41 豆豆
生活随笔 收集整理的這篇文章主要介紹了 iOS中的图像处理(一)——基础滤镜 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

最近在稍微做一些整理,翻起這部分的代碼,發現是兩個多月前的了。

這里討論的是基于RGBA模型下的圖像處理,即將變換作用在每個像素上。

代碼是以UIImage的category形式存在的:

?

[cpp] view plaincopy
  • typedef?struct?_singleRGBA??
  • {??
  • ????unsigned?char?red;??
  • ????unsigned?char?green;??
  • ????unsigned?char?blue;??
  • ????unsigned?char?alpha;??
  • }?RGBA;??
  • ??
  • @interface?UIImage?(ImageFilter)??

  • 首先,我們需要獲得目標圖像的位圖信息;然后對每個像素進行變換;最后再生成圖像。

    ?

    [cpp] view plaincopy
  • -?(UIImage*)applyFilter:(FilterFunction)filter?context:(void*)context??
  • {??
  • ????CGImageRef?inImage?=?self.CGImage;??
  • ????CFDataRef?m_DataRef?=?CGDataProviderCopyData(CGImageGetDataProvider(inImage));??
  • ????UInt8?*m_PixelBuf?=?(UInt8?*)CFDataGetBytePtr(m_DataRef);??
  • ??????
  • ????int?length?=?CFDataGetLength(m_DataRef);??
  • ??????
  • ????for?(int?i=0;?i<length;?i+=4)?{??
  • ????????filter(m_PixelBuf,?i,?context);??
  • ????}??
  • ??????
  • ????CGContextRef?ctx?=?CGBitmapContextCreate(m_PixelBuf,??
  • ?????????????????????????????????????????????CGImageGetWidth(inImage),??
  • ?????????????????????????????????????????????CGImageGetHeight(inImage),??
  • ?????????????????????????????????????????????CGImageGetBitsPerComponent(inImage),??
  • ?????????????????????????????????????????????CGImageGetBytesPerRow(inImage),??
  • ?????????????????????????????????????????????CGImageGetColorSpace(inImage),??
  • ?????????????????????????????????????????????CGImageGetBitmapInfo(inImage)??
  • ?????????????????????????????????????????????);??
  • ??????
  • ????CGImageRef?imageRef?=?CGBitmapContextCreateImage(ctx);??
  • ????CGContextRelease(ctx);??
  • ????UIImage?*finalImage?=?[UIImage?imageWithCGImage:imageRef];??
  • ????CGImageRelease(imageRef);??
  • ????CFRelease(m_DataRef);??
  • ??????
  • ????return?finalImage;??
  • }??

  • 其中,FilterFunction聲明如下:

    ?

    [cpp] view plaincopy
  • typedef?void?(*FilterFunction)(UInt8?*pixelBuf,?UInt32?offset,?void?*context);??

  • 在此基礎上,我們可以把每個變換操作獨立出來,比如調整亮度、對比度、色調、透明度等:

    ?

    [cpp] view plaincopy
  • void?filterOpacity(UInt8?*pixelBuf,?UInt32?offset,?void?*context)??
  • {??
  • ????double?val?=?*((double*)context);??
  • ??????
  • ????int?a?=?offset+3;??
  • ??????
  • ????int?alpha?=?pixelBuf[a];??
  • ??????
  • ????pixelBuf[a]?=?SAFECOLOR(alpha?*?val);??
  • }??
  • ??
  • void?filterBrightness(UInt8?*pixelBuf,?UInt32?offset,?void?*context)??
  • {??
  • ????double?t?=?*((double*)context);??
  • ??????
  • ????int?r?=?offset;??
  • ????int?g?=?offset+1;??
  • ????int?b?=?offset+2;??
  • ??????
  • ????int?red?=?pixelBuf[r];??
  • ????int?green?=?pixelBuf[g];??
  • ????int?blue?=?pixelBuf[b];??
  • ??????
  • ????pixelBuf[r]?=?SAFECOLOR(red?*?t);??
  • ????pixelBuf[g]?=?SAFECOLOR(green?*?t);??
  • ????pixelBuf[b]?=?SAFECOLOR(blue?*?t);??
  • }??
  • ??
  • void?filterSaturation(UInt8?*pixelBuf,?UInt32?offset,?void?*context)??
  • {??
  • ????double?t?=?*((double*)context);?//?t?(-?[0,?2]??
  • ??????
  • ????int?r?=?offset;??
  • ????int?g?=?offset+1;??
  • ????int?b?=?offset+2;??
  • ??????
  • ????int?red?=?pixelBuf[r];??
  • ????int?green?=?pixelBuf[g];??
  • ????int?blue?=?pixelBuf[b];??
  • ??????
  • ????red?=?red?*?(0.3086?*?(1-t)?+?t)?+?green?*?(0.6094?*?(1-t))?+?blue?*?(0.0820?*?(1-t));??
  • ????green?=?red?*?(0.3086?*?(1-t))?+?green?*?((0.6094?*?(1-t))?+?t)?+?blue?*?(0.0820?*?(1-t));??
  • ????blue?=?red?*?(0.3086?*?(1-t))?+?green?*?(0.6094?*?(1-t))?+?blue?*?((0.0820?*?(1-t))?+?t);??
  • ??????
  • ????pixelBuf[r]?=?SAFECOLOR(red);??
  • ????pixelBuf[g]?=?SAFECOLOR(green);??
  • ????pixelBuf[b]?=?SAFECOLOR(blue);??
  • }??
  • ??
  • void?filterContrast(UInt8?*pixelBuf,?UInt32?offset,?void?*context)??
  • {??
  • ????double?t?=?*((double*)context);?//?t?(-?[0,?10]??
  • ??????
  • ????int?r?=?offset;??
  • ????int?g?=?offset+1;??
  • ????int?b?=?offset+2;??
  • ??????
  • ????int?red?=?pixelBuf[r];??
  • ????int?green?=?pixelBuf[g];??
  • ????int?blue?=?pixelBuf[b];??
  • ??????
  • ????red?=?red?*?t?+?128?*?(1-t);??
  • ????green?=?green?*?t?+?128?*?(1-t);??
  • ????blue?=?blue?*?t?+?128?*?(1-t);??
  • ??????
  • ????pixelBuf[r]?=?SAFECOLOR(red);??
  • ????pixelBuf[g]?=?SAFECOLOR(green);??
  • ????pixelBuf[b]?=?SAFECOLOR(blue);??
  • }??
  • ??
  • void?filterPosterize(UInt8?*pixelBuf,?UInt32?offset,?void?*context)??
  • {??
  • ????double?levels?=?*((double*)context);??
  • ????if?(levels?==?0)?levels?=?1;?//?avoid?divide?by?zero??
  • ????int?step?=?255?/?levels;??
  • ??????
  • ????int?r?=?offset;??
  • ????int?g?=?offset+1;??
  • ????int?b?=?offset+2;??
  • ??????
  • ????int?red?=?pixelBuf[r];??
  • ????int?green?=?pixelBuf[g];??
  • ????int?blue?=?pixelBuf[b];??
  • ??????
  • ????pixelBuf[r]?=?SAFECOLOR((red?/?step)?*?step);??
  • ????pixelBuf[g]?=?SAFECOLOR((green?/?step)?*?step);??
  • ????pixelBuf[b]?=?SAFECOLOR((blue?/?step)?*?step);??
  • }??
  • ??
  • void?filterDesaturate(UInt8?*pixelBuf,?UInt32?offset,?void?*context)??
  • {??
  • ????int?r?=?offset;??
  • ????int?g?=?offset+1;??
  • ????int?b?=?offset+2;??
  • ??????
  • ????int?red?=?pixelBuf[r];??
  • ????int?green?=?pixelBuf[g];??
  • ????int?blue?=?pixelBuf[b];??
  • ??????
  • ????red?=?red?*?0.3086?+?green?*?0.6094?+?blue?*?0.0820;??
  • ????green?=?red?*?0.3086?+?green?*?0.6094?+?blue?*?0.0820;??
  • ????blue?=?red?*?0.3086?+?green?*?0.6094?+?blue?*?0.0820;??
  • ??????
  • ????pixelBuf[r]?=?SAFECOLOR(red);??
  • ????pixelBuf[g]?=?SAFECOLOR(green);??
  • ????pixelBuf[b]?=?SAFECOLOR(blue);??
  • }??
  • ??
  • void?filterInvert(UInt8?*pixelBuf,?UInt32?offset,?void?*context)??
  • {??
  • ????int?r?=?offset;??
  • ????int?g?=?offset+1;??
  • ????int?b?=?offset+2;??
  • ??????
  • ????int?red?=?pixelBuf[r];??
  • ????int?green?=?pixelBuf[g];??
  • ????int?blue?=?pixelBuf[b];??
  • ??????
  • ????pixelBuf[r]?=?SAFECOLOR(255-red);??
  • ????pixelBuf[g]?=?SAFECOLOR(255-green);??
  • ????pixelBuf[b]?=?SAFECOLOR(255-blue);??
  • }??
  • ??
  • void?filterTint(UInt8?*pixelBuf,?UInt32?offset,?void?*context)??
  • {??
  • ????RGBA?*rgbaArray?=?(RGBA*)context;??
  • ????RGBA?maxRGBA?=?rgbaArray[0];??
  • ????RGBA?minRGBA?=?rgbaArray[1];??
  • ??????
  • ????int?r?=?offset;??
  • ????int?g?=?offset+1;??
  • ????int?b?=?offset+2;??
  • ??????
  • ????int?red?=?pixelBuf[r];??
  • ????int?green?=?pixelBuf[g];??
  • ????int?blue?=?pixelBuf[b];??
  • ??????
  • ????pixelBuf[r]?=?SAFECOLOR((red?-?minRGBA.red)?*?(255.0?/?(maxRGBA.red?-?minRGBA.red)));??
  • ????pixelBuf[g]?=?SAFECOLOR((green?-?minRGBA.green)?*?(255.0?/?(maxRGBA.green?-?minRGBA.green)));??
  • ????pixelBuf[b]?=?SAFECOLOR((blue?-?minRGBA.blue)?*?(255.0?/?(maxRGBA.blue?-?minRGBA.blue)));??
  • }??

  • 其中SAFECOLOR宏如下:

    [cpp] view plaincopy
  • #define?SAFECOLOR(color)?MIN(255,MAX(0,color))??

  • 最后,拿一張帥氣的Andy照片來實踐下,希望沒有侵犯到肖像權。
    原圖如下:


    通過以下四種變換,可以分別得到四張處理過的圖片:

    ?

    [cpp] view plaincopy
  • return?[originImage?changeOpacityByFactor:0.5];??

  • [cpp] view plaincopy
  • return?[originImage?changeBrightnessByFactor:1.2];??

  • [cpp] view plaincopy
  • return?[originImage?changeSaturationByFactor:2.0];??

  • [cpp] view plaincopy
  • return?[originImage?tintWithMaxRGBA:(RGBA){190,?190,?230}?minRGBA:(RGBA){50,?35,?10}];??

  • ??

    ?



    版權聲明:本文為博主原創文章,未經博主允許不得轉載。

    總結

    以上是生活随笔為你收集整理的iOS中的图像处理(一)——基础滤镜的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。