【发布时间】:2019-10-26 19:38:14
【问题描述】:
我正在使用人脸检测服务,给定一张图片会返回我的人脸地标位置。我的目标是将这些地标定位在我在屏幕上显示的图片上。
我的想法是使用带有图像视图的 AbosluteLayout 并将地标放置在图片上。重叠效果很好。问题是地标的点指的是原始图片大小坐标,而渲染图像的大小完全不同。我目前正在使用 AspectFit,因此在保留纵横比的 AbsoluteLayout 中显示完整图片,通常带有信箱。
我尝试的是考虑屏幕密度并将其应用于原始地标点:
rightEyePoint.X = Convert.ToInt32(rightEyePoint.X / displayDensity);
它越来越近,但不是在所有照片上(不同于风景/肖像)。
然后我想我可能想知道考虑到原始图像的渲染图像的比例因子,然后我可以转换所有地标点,但我不知道该怎么做。我尝试创建一个自定义图像视图和渲染器以尝试从中获取比例计算,但没有成功,因为我没有干预本地图像组件的计算位置:
public class CustomImageView : Image
{
protected override SizeRequest OnMeasure(double widthConstraint, double heightConstraint)
{
return base.OnMeasure(widthConstraint, heightConstraint);
}
protected override void OnSizeAllocated(double width, double height)
{
base.OnSizeAllocated(width, height);
}
protected override void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
base.OnPropertyChanged(propertyName);
}
}
public class CustomImageViewRenderer : ImageRenderer
{
public CustomImageViewRenderer(Context context) : base(context) { }
protected override void OnElementChanged(ElementChangedEventArgs<Image> e)
{
base.OnElementChanged(e);
if(e.NewElement != null)
{
var image = Control as ImageView;
}
}
protected override void OnSizeChanged(int w, int h, int oldw, int oldh)
{
base.OnSizeChanged(w, h, oldw, oldh);
}
protected override Task TryUpdateBitmap(Image previous = null)
{
return base.TryUpdateBitmap(previous);
}
}
然后我想我可以自己计算当前渲染图像的大小,但我似乎无法得到它。所以我只得到 xamarin 表单图像组件大小,而不是其中呈现的图像。在这一点上,我认为我可以根据纵横比计算渲染图像的大小,因为我正在使用 AspectFit,但在此过程中卡住了。
axml(示例):
<AbsoluteLayout BackgroundColor="Fuchsia" HorizontalOptions="Fill" VerticalOptions="Fill">
<Controls:PinchToZoomContainer HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand" CurrentPosition="{Binding CurrentPhotoPosition}" CurrentScale="{Binding CurrentPhotoScale}" AbsoluteLayout.LayoutBounds="0, 0, 1, 1" AbsoluteLayout.LayoutFlags="All" IsEnabled="{ Binding CurrentStep, Converter={StaticResource checkIntToBooleanValueConverter}, ConverterParameter=2}">
<Image BackgroundColor="Blue" Source="{Binding CurrentPhotoPath}">
<Image.Behaviors>
<behaviors:EventToCommandBehavior
EventName="SizeChanged"
Command="{Binding ImageSizeChangedCommand}"/>
</Image.Behaviors>
</Image>
<!--<Controls:CustomImageView Source="{Binding CurrentPhotoPath}" BackgroundColor="Purple" SizeChanged=""/-->
</Controls:PinchToZoomContainer>
<!-- calculated landmarks -->
<Controls:LandmarkView
Padding="2"
DragMode="TouchAndRelease"
LBounds="{Binding HairStartLandmarkBounds, Mode=TwoWay}"
DragDirection="Vertical"
HorizontalOptions="FillAndExpand"
VerticalOptions="Start"
IsVisible="{ Binding CurrentStep, Converter={StaticResource checkIntToBooleanValueConverter}, ConverterParameter=3}"
x:Name="HairStartLandmark"
ToggleDraggingCommand="{Binding HairStartLandmarkTouchedCommand}">
<Controls:LandmarkView.Content>
<AbsoluteLayout>
<Image BackgroundColor="Red"
WidthRequest="{Binding LandmarkLineWidth}"
AbsoluteLayout.LayoutBounds= "{Binding LandmarkLineXPos}"
AbsoluteLayout.LayoutFlags="YProportional,WidthProportional"/>
<ffimageloading:CachedImage
WidthRequest="{Binding HairStartLandmarkIconSize}"
HeightRequest="{Binding HairStartLandmarkIconSize}"
Source="{Binding HairStartLandmarkIcon, Converter={StaticResource SvgImageSourceConverter}}">
</ffimageloading:CachedImage>
</AbsoluteLayout>
</Controls:LandmarkView.Content>
</Controls:LandmarkView>
</AbsoluteLayout>
所以我的问题是,如何轻松获取渲染图像坐标系原点和比例因子以应用于地标点坐标并将它们正确定位在渲染图像上?
更新:
我添加了我所拥有的和我认为需要的当前状态的图像。蓝色背景是 Xamarin.Forms Image 视图背景:
非常感谢
【问题讨论】:
-
您是否尝试过获取图像边界? docs.microsoft.com/en-us/dotnet/api/…
-
是的,这是很容易知道的信息,但正如我在问题中所说,您只能获得 XamarinForms 图像边界,而不是渲染图像框(可能有信箱)
标签: c# image xamarin.forms