我为Wikitude创建了一个新插件 . 我想将识别的图像发送到另一个API . 首先,我必须得到图像,但我失败了 . 我也在Wikitude论坛上问了这个问题,但没有人回答 . 这是我的插件代码:我正在使用Wikitude 6.0和VisualStudio 2017

public class Plugin02 : Com.Wikitude.Common.Plugins.Plugin
{
    public Plugin02(string p0) : base(p0)
    {
    }
    public override void CameraFrameAvailable(Frame p0)
    {
        try
        {
            // try 1
            BitmapFactory.Options Options = new BitmapFactory.Options { InSampleSize = 1 };
            Bitmap bitmap = BitmapFactory.DecodeByteArray(p0.GetData(), 0, p0.GetData().Length, Options);
            SaveBitmap(bitmap);
            // result : bitmap is always null


            //try 2
            var yuv = new YuvImage(p0.GetData(), ImageFormatType.Nv21, p0.Size.Width, p0.Size.Height, null);
            // var bmp = a.b(currentFrame.GetData(), currentFrame.GetData().Length, currentFrame.Size.Width, currentFrame.Size.Height);
            var ms = new MemoryStream();
            var quality = 100;   // adjust this as needed
            yuv.CompressToJpeg(new Rect(0, 0, yuv.Width, yuv.Height), quality, ms);
            var jpegData = ms.ToArray();
            Bitmap bitmap2 = BitmapFactory.DecodeByteArray(jpegData, 0, jpegData.Length);
            SaveBitmap(bitmap2);
            // result : image is not clear
        }
        catch (System.Exception ex) { }
    }
    void SaveBitmap(Bitmap bitmap)
    {
        var sdCardPath = Android.OS.Environment.ExternalStorageDirectory.AbsolutePath;
        var filePath = System.IO.Path.Combine(sdCardPath, DateTime.Now.Millisecond.ToString() + ".jpg");
        var stream = new FileStream(filePath, FileMode.Create);
        bitmap.Compress(Bitmap.CompressFormat.Png, 100, stream);
        stream.Close();
    }
    public override void Update(RecognizedTarget[] p0)
    {

    }
    protected override void Initialize()
    {
        base.Initialize();
    }
    protected override void Pause()
    {
        base.Pause();
    }
    protected override void Resume(long p0)
    {
        base.Resume(p0);
    }
    protected override void Destroy()
    {
        base.Destroy();
    }

}

这是我的新代码:

public class Plugin01 : Com.Wikitude.Common.Plugins.Plugin
{
    TesseractApi api;
    public Plugin01(string p0) : base(p0)
    {
        api = new TesseractApi(Application.Context, AssetsDeployment.OncePerVersion);
        api.Init("eng");
    }


    Frame currentFrame = null;
    public override void CameraFrameAvailable(Frame p0)
    {
        try
        {
            var data = p0.GetData();
            currentFrame = p0;
        }
        catch (System.Exception ex) { }
    }

    public override void Update(RecognizedTarget[] p0)
    {
        if (p0 != null)
        {
            if (currentFrame != null)
            {
                ConvertYuvToJpeg(currentFrame, p0[0]);
            }
        }
    }
    protected override void Initialize()
    {
        base.Initialize();
    }
    protected override void Pause()
    {
        base.Pause();
    }
    protected override void Resume(long p0)
    {
        base.Resume(p0);
    }
    protected override void Destroy()
    {
        base.Destroy();
    }

    private void ConvertYuvToJpeg(Frame frame, RecognizedTarget p00)
    {
        try
        {
            YuvImage yuvimage = new YuvImage(frame.GetData(), ImageFormatType.Nv21, frame.Size.Width, frame.Size.Height, null);
            var outStream = new MemoryStream();
            var left = p00.TargetPositionInCameraFrame.Origin.GetY() + 10;
            var top = p00.TargetPositionInCameraFrame.Origin.GetX()+20;
            var right = left + p00.TargetPositionInCameraFrame.Size.Width;
            var bottom = top + p00.TargetPositionInCameraFrame.Size.Height;
            Rect rect = new Rect(left, top, right, bottom);

            yuvimage.CompressToJpeg(rect, 100, outStream);
            Bitmap bmp = BitmapFactory.DecodeByteArray(outStream.ToArray(), 0, outStream.ToArray().Length);

            Matrix mtx = new Matrix();
            mtx.PreRotate(90);
            bmp = Bitmap.CreateBitmap(bmp, 0, 0, bmp.Width, bmp.Height, mtx, false);

            var outStream1 = new MemoryStream();
            bmp.Compress(Bitmap.CompressFormat.Png, 100, outStream1);
            var bmpA = bmp.Copy(Bitmap.Config.Argb8888, true);

            api.SetImage(outStream1);
            //api.Results(Tesseract.PageIteratorLevel.Block);
            if (api.Text != null)
            {
            }

            var sdCardPath = Android.OS.Environment.ExternalStorageDirectory.AbsolutePath;
            var filePath = System.IO.Path.Combine(sdCardPath, DateTime.Now.Millisecond.ToString() + ".jpg");
            var stream = new FileStream(filePath, FileMode.Create);
            bmp.Compress(Bitmap.CompressFormat.Jpeg, 100, stream);
            stream.Close();
        }
        catch (System.Exception ex) { }

    }

}

这是图像样本:
enter image description here

根据什么wikitude support said图像格式为YV12 for Android,我找不到任何方式将其转换为RGB或类似唯一的一种是Nv21格式 .

我已经按照你的说法添加了YUV到RGB转换器,这里是新代码,但是出了点问题 . getData()的长度大于width * height .

public override void Update(RecognizedTarget[] p0)
    {
        if (p0 != null)
        {
            if (currentFrame != null)
            {
                //ConvertYuvToJpeg(currentFrame, p0[0]);
                ConvertYuvToRGB(currentFrame, p0[0]);
            }
        }
    }
    private void ConvertYuvToRGB(Frame frame, RecognizedTarget p00)
    {
        try
        {
            var rgbData = convertYUV420_NV21toARGB8888(frame.GetData(), frame.Size.Width, frame.Size.Height);
            var bitmap = Bitmap.CreateBitmap(100, 100, Bitmap.Config.Argb8888);
            // vector is your int[] of ARGB 
            bitmap.CopyPixelsFromBuffer(Java.Nio.IntBuffer.Wrap(rgbData));
            var sdCardPath = Android.OS.Environment.ExternalStorageDirectory.AbsolutePath;
            var filePath = System.IO.Path.Combine(sdCardPath, DateTime.Now.Millisecond.ToString() + ".jpg");
            var stream = new FileStream(filePath, FileMode.Create);
            bitmap.Compress(Bitmap.CompressFormat.Jpeg, 100, stream);
            stream.Close();
        }
        catch (System.Exception ex) { }
    }
    public static int[] convertYUV420_NV21toARGB8888(byte[] data, int width, int height)
    {
        int size = width * height;
        int offset = size;
        int[] pixels = new int[size];
        int u, v, y1, y2, y3, y4;

        // i along Y and the final pixels
        // k along pixels U and V
        for (int i = 0, k = 0; i < size; i += 2, k += 2)
        {
            y1 = data[i] & 0xff;
            y2 = data[i + 1] & 0xff;
            y3 = data[width + i] & 0xff;
            y4 = data[width + i + 1] & 0xff;

            u = data[offset + k] & 0xff;
            v = data[offset + k + size / 4] & 0xff;
            v = v - 128;
            u = u - 128;

            pixels[i] = convertYUVtoARGB(y1, u, v);
            pixels[i + 1] = convertYUVtoARGB(y2, u, v);
            pixels[width + i] = convertYUVtoARGB(y3, u, v);
            pixels[width + i + 1] = convertYUVtoARGB(y4, u, v);

            if (i != 0 && (i + 2) % width == 0)
                i += width;
        }

        return pixels;
    }
    private static int convertYUVtoARGB(int y, int u, int v)
    {
        int r = y + (int)(1.772f * v);
        int g = y - (int)(0.344f * v + 0.714f * u);
        int b = y + (int)(1.402f * u);
        r = r > 255 ? 255 : r < 0 ? 0 : r;
        g = g > 255 ? 255 : g < 0 ? 0 : g;
        b = b > 255 ? 255 : b < 0 ? 0 : b;
        return (int)(4278190080 | ((r + 16) | ((g + 8) | b)));
    }