我设置的NavBar的背景,这个代码在视网膜和非Retina显示屏的伟大工程。 有一个@ 2x和正常图像。 所以,所有的好:
UINavigationBar.Appearance.SetBackgroundImage(
GetImage(ImageTheme.menubar), UIBarMetrics.Default);
现在,当我应用此ChangeHue()
变换到图像调整其色调,视网膜上显示的图像是大小的两倍。 非Retina显示屏的罚款:
UINavigationBar.Appearance.SetBackgroundImage(
ChangeHue(GetImage(ImageTheme.menubar)), UIBarMetrics.Default);
...
UIImage ChangeHue(UIImage originalImage){
var hueAdjust = new CIHueAdjust() {
Image = CIImage.FromCGImage(originalImage.CGImage),
Angle = hue * (float)Math.PI / 180f // angles to radians
};
var output = hueAdjust.OutputImage;
var context = CIContext.FromOptions(null);
var cgimage = context.CreateCGImage(output, output.Extent);
var i = UIImage.FromImage(cgimage);
return i;
}
下面是结果在非视网膜和视网膜显示被施加色相后:
忽略那些黑客,并在编辑这行ChangeHue
方法:
var i = UIImage.FromImage(cgimage);
要做到这一点,而不是:
float scale = 1f;
if (UIScreen.MainScreen.RespondsToSelector (new MonoTouch.ObjCRuntime.Selector ("scale"))) {
scale = UIScreen.MainScreen.Scale; // will be 2.0 for Retina
}
var i = new UIImage(cgimage, scale, UIImageOrientation.Up);
这应返回UIImage
对象,它是具有在正常显示正确的“规模”的信息UINavigationBar
。
我从来没有尝试过的CoreImage但是,对于CoreGraphics中,你需要使用UIGraphics.BeginImageContextWithOptions
并指定0
缩放(因此它会自动地为双方的Retina和非Retina显示屏来完成)。
所以我想尝试的第一件事就是更换您:
var context = CIContext.FromOptions(null);
用下面的块:
UIGraphics.BeginImageContextWithOptions (new SizeF (size, size), false, 0);
using (var c = UIGraphics.GetCurrentContext ()) {
var context = CIContext.FromContext (c);
...
}
UIGraphics.EndImageContext ();
UPDATE: FromContext
不可用的iOS(它是OSX的具体),所以上面的代码将无法正常工作。
建档的错误与MonoTouch的团队。 不久将发布的解决方案。
我有三个“黑客”建议现在:
哈克#1
要强制的程度通过更换此行裁剪图像:
var cgimage = context.CreateCGImage(output, output.Extent);
有了这个:
var extent = output.Extent;
if (UIScreen.MainScreen.RespondsToSelector (new MonoTouch.ObjCRuntime.Selector("scale"))) {
if (UIScreen.MainScreen.Scale == 2f) {
extent = new System.Drawing.RectangleF(extent.X, extent.Y, extent.Width / 2f, extent.Height / 2f);
}
}
var cgimage = context.CreateCGImage(output, extent);
然而,你“丢失”调整图像上的视网膜分辨率(它使用的@ 2倍的图像作为源,但只应用过滤器后显示它的左下象限,由于图像原点开始在左下) 。
哈克#2
按照同样的思路,可以缩放从返回的图像ChangeHue
方法,使其不扩大超出了导航栏:
var hued = ChangeHue (navBarImage);
if (hued.RespondsToSelector(new MonoTouch.ObjCRuntime.Selector("scale")))
hued = hued.Scale (new System.Drawing.SizeF(320, 47));
UINavigationBar.Appearance.SetBackgroundImage (hued, UIBarMetrics.Default);
不幸的是,你又“丢失”的Retina分辨率,但至少显示正确的图像(只是下采样到320宽)。
哈克#3
你可以保存过滤的图像到磁盘,然后设置UIAppearance
使用“盘”上的图像文件。 代码如下所示:
bool retina = false;
if (UIScreen.MainScreen.RespondsToSelector (new MonoTouch.ObjCRuntime.Selector ("scale"))) {
if (UIScreen.MainScreen.Scale == 2f) {
retina = true;
}
}
if (retina) {
NSError err; // unitialized
UIImage img = ChangeHue (navBarImage);
img.AsPNG ().Save ("tempNavBar@2x.png", true, out err);
if (err != null && err.Code != 0) {
// error handling
}
UINavigationBar.Appearance.SetBackgroundImage (UIImage.FromFile ("tempNavBar.png"), UIBarMetrics.Default);
} else {
UINavigationBar.Appearance.SetBackgroundImage (ChangeHue (navBarImage), UIBarMetrics.Default);
}
这最后黑客的好处是,图像看起来正确的(即视网膜分辨率保存)。
我仍然在寻找“完美”的解决方案,但至少这些想法“修复”你的问题单向或-另一...
文章来源: MonoTouch: Doubling Appearance Image size when Hue adjusted on Retina display