在Xamarin中将StackLayout转换为Image

时间:2016-09-07 13:19:14

标签: xamarin.android xamarin.forms

我正在开发Xmarin Forms(PCL)项目,我想将StackLayout转换为Image / buffer并将其发送到打印机进行硬打印。

任何人都可以建议如何(Xamarin.Android& Xamarin.iOS)。

2 个答案:

答案 0 :(得分:1)

你做不到。 Xamarin没有那种功能。您应该为您的UIComponent编写一个渲染器。

幸运的是,有一个Objective-C iOS实现,还有一个Android实现。你可以激励他们。

答案 1 :(得分:0)

从我个人使用过的this链接中提取,不久之后,以下代码将截取整个页面的截图。

我最后修改代码只是截取页面上特定视图的截图,还改变了一些其他的东西,但这个例子是我的基础,所以让我知道你是否愿意看到代码和/或如果下面的内容不适合你。

首先在Forms项目中创建一个界面, IScreenshotManager.cs ,例如:

public interface IScreenshotManager {
    Task<byte[]> CaptureAsync();
}

现在我们需要在Android中实现我们的界面, ScreenshotManager_Android.cs ,例如:

public class ScreenshotManager : IScreenshotManager {

    public static Activity Activity { get; set; }

    public async System.Threading.Tasks.Task<byte[]> CaptureAsync() {

        if(Activity == null) {

            throw new Exception("You have to set ScreenshotManager.Activity in your Android project");
        }

        var view = Activity.Window.DecorView;
        view.DrawingCacheEnabled = true;

        Bitmap bitmap = view.GetDrawingCache(true);

        byte[] bitmapData;

        using (var stream = new MemoryStream()) {
            bitmap.Compress(Bitmap.CompressFormat.Png, 0, stream);
            bitmapData = stream.ToArray();
        }

        return bitmapData;
    }
}

然后在ScreenshotManager.Activity中设置MainActivity

public class MainActivity : Xamarin.Forms.Platform.Android.FormsApplicationActivity {

    protected override async void OnCreate(Android.OS.Bundle bundle) {
        ...
        ScreenshotManager.Activity = this; //There are better ways to do this but this is what the example from the link suggests
        ...
    }
}

最后我们在iOS上实现这一点,让我们疯狂并命名为 ScreenshotManager_iOS.cs

public class ScreenshotManager : IScreenshotManager {
    public async System.Threading.Tasks.Task<byte[]> CaptureAsync() {
        var view = UIApplication.SharedApplication.KeyWindow.RootViewController.View;

        UIGraphics.BeginImageContext(view.Frame.Size);
        view.DrawViewHierarchy(view.Frame, true);
        var image = UIGraphics.GetImageFromCurrentImageContext();
        UIGraphics.EndImageContext();

        using(var imageData = image.AsPNG()) {
            var bytes = new byte[imageData.Length];
            System.Runtime.InteropServices.Marshal.Copy(imageData.Bytes, bytes, 0, Convert.ToInt32(imageData.Length));
            return bytes;
        }
    }
}