unity android模糊ios清晰,Unity3D-通过调用iOS原生代码将图片进行高斯模糊

之前一直想使用Shader去做高斯模糊特效,后面发现图片过大的话,效率真的是相当的不理想。

后来在网上看到说iOS本身是有将图片处理成高斯模糊的功能的,想想也确实,苹果设备的背景经常会出现模糊特效,那他们的算法应该很快速的,于是突发奇想,如果将要做模糊处理的图片,传到原生端然后处理成模糊图片之后,再传回来使用,不就可以达到这个目的了么!

首先要知道这个的局限性,不能实时的去做,这是什么意思呢,如果截图这一下也是会有一点卡的,如果实时处理的话,肯定会不流畅。

还有一个,图片的格式,不能是Unity的压缩格式,因为我没法解压缩图片,那穿过去的图片就没法生成正常图片了。

最后,图片要是可读写的,否则拿不到图片的二进制数据,也没法做;

那么怎么做呢,关于Unity桥接原生的我在之前的文章说过了,可以参考这里:Unity和iOS互通

原生代码:

- (void) imageToBlurImage:(NSString *)media radius:(float)radius {

if(media.length != 0) {// 1、创建输入图像,CIImage类型,这里使用从外部传过来的图片。

NSData *imageData = [[NSData alloc]initWithBase64EncodedString:media options:0];

CIImage* inputImage = [CIImage imageWithData:imageData];

// 2、构建一个滤镜图表

// CIColor* sepiaColor = [CIColor colorWithRed:0.76 green:0.65 blue:0.54];

// // 2.1 先构建一个 CIColorMonochrome 滤镜,并配置输入图像与滤镜参数

// CIFilter* monochromeFilter = [CIFilter filterWithName:@"CIColorMonochrome" withInputParameters:@{@"inputColor":sepiaColor,@"inputIntensity":@1.0}];

// [monochromeFilter setValue:inputImage forKey:@"inputImage"];

// // 2.2 先构建一个 CIVignette 滤镜

// CIFilter* vignetteFilter = [CIFilter filterWithName:@"CIVignette" withInputParameters:@{@"inputRadius":@1.0, @"inputIntensity":@1.0}];

// [vignetteFilter setValue:monochromeFilter.outputImage forKey:@"inputImage"];

NSNumber* numRad = [NSNumber numberWithFloat:radius];

CIFilter* gaussianFilter = [CIFilter filterWithName:@"CIGaussianBlur" withInputParameters:@{@"inputRadius":numRad}];

[gaussianFilter setValue:inputImage forKey:@"inputImage"];

// 3、得到一个滤镜处理后的图片,并转换至 UIImage

// 创建一个 CIContext

CIContext* ciContext = [CIContext contextWithOptions:nil];

// 将 CIImage 过渡到 CGImageRef 类型

CGImageRef cgImage = [ciContext createCGImage:gaussianFilter.outputImage fromRect:inputImage.extent];

// 最后转换为 UIImage 类型

UIImage* uiImage = [UIImage imageWithCGImage:cgImage];

// 将得到的图片转化成图片数据,通过SendMessage传送到Unity端

NSData *imgData = UIImagePNGRepresentation(uiImage);

NSString *_encodeImageStr = [imgData base64EncodedStringWithOptions:NSDataBase64DecodingIgnoreUnknownCharacters];

if (_encodeImageStr == nil){

UnitySendMessage( "GJCNativeShare", "ToBlurImageFailed", [GJC_DataConvertor NSStringToChar:@"iamge change error! the image format is not support!"]);

}else{

UnitySendMessage( "GJCNativeShare", "ToBlurImageSuccess", _encodeImageStr.UTF8String);

}

}else{

UnitySendMessage( "GJCNativeShare", "ToBlurImageFailed", [GJC_DataConvertor NSStringToChar:@"iamge data is null!"]);

}

}

extern "C" {

void _GJC_ToBlurImage(char* encodedMedia, float radius){

NSString *media = [GJC_DataConvertor charToNSString:encodedMedia];

[[GJCSocialShare sharedInstance] imageToBlurImage:media radius:radius];

}

}

然后Unity这边:

[DllImport ("__Internal")]

private static extern bool _GJC_ToBlurImage(string encodedMedia, float radius);

///

/// 调用原生的高斯模糊处理,传递一张图片过去,得到处理之后的图片

///

/// 分享的图片

public void TextureToBlur(Texture2D texture, float radius) {

Debug.Log("TextureToBlur");

#if UNITY_IPHONE && !UNITY_EDITOR

if(texture != null) {

Debug.Log("TextureToBlur: Texture");

string bytesString = System.Convert.ToBase64String (texture.EncodeToPNG());

// string bytesString = System.Convert.ToBase64String (texture.GetRawTextureData());

_GJC_ToBlurImage(bytesString, radius);

}else{

ToBlurImageFailed("texture is null!");

}

#else

// string bytesString = System.Convert.ToBase64String (texture.EncodeToEXR());

// Texture2D newTexture = new Texture2D(1,1);

// newTexture.LoadRawTextureData(texture.GetRawTextureData());

// string bytesString = System.Convert.ToBase64String (texture.EncodeToPNG());

ToBlurImageFailed("this platform is not support!");

#endif

}

从原生的回调:

///

/// 图片转换成Blur效果之后,回调的结果

///

/// Base64.

private void ToBlurImageSuccess(string base64)

{

Debug.Log ("Native To ToBlurImageSuccess");

if(onToBlurImage != null)

{

onToBlurImage("Success", base64);

}

}

private void ToBlurImageFailed(string error){

Debug.Log ("Native To ToBlurImageFailed: " + error);

if(onToBlurImage != null)

{

onToBlurImage("Failed", error);

}

}

将iOS传递过来的数据,转换成图片

///

/// 将ios传过的string转成u3d中的texture

///

///

///

public static Texture2D Base64StringToTexture2D(string base64)

{

Debug.Log ("Run Base64StringToTexture2d");

Texture2D tex = new Texture2D(1,1);

try

{

byte[] bytes = System.Convert.FromBase64String(base64);

tex.LoadImage(bytes);

tex.hideFlags = HideFlags.DontSave;

tex.filterMode = FilterMode.Point;

tex.wrapMode = TextureWrapMode.Clamp;

}

catch(System.Exception ex)

{

Debug.Log ("Create Texture2D Failed!!");

Debug.LogError(ex.Message);

}

return tex;

}

自己使用了之后,速度还是蛮快的,目前这个用在一些固定大背景模糊的位置,实时的话,还是想想如何优化Shader去做吧。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值