android - 如何在xamarin android中旋转YuvImage

标签 android image rotation xamarin.forms

我正在 Android 界面中将图像的字节数组转换为 YuvImage,用于我的 xamarin 应用程序,如下所示

      public KeyValuePair<string, string> CaptureImageFromBarcode(byte[] bt, int width, int height)
    {

        Java.IO.FileOutputStream outStream = null;
        Android.Graphics.YuvImage yuvimage = new Android.Graphics.YuvImage(bt, Android.Graphics.ImageFormat.Nv21, width, height,null);
        MemoryStream baos = new MemoryStream();
        yuvimage.CompressToJpeg(new Android.Graphics.Rect(0, 0, width, height), 80, baos);
        var directory = Android.OS.Environment.GetExternalStoragePublicDirectory(Android.OS.Environment.DirectoryPictures);
        string filenamefile = DateTime.Now.Ticks.ToString() + ".jpg";
        string filename = System.IO.Path.Combine(directory.AbsolutePath, filenamefile);
        outStream = new Java.IO.FileOutputStream(filename);
        outStream.Write(baos.ToArray());
        outStream.Close();
        return new KeyValuePair<string, string>(filenamefile, filename);
    }

这里我将图像保存到磁盘。但是保存的图像向左旋转了90度。所以我想保存正确旋转90度的图像。我尝试了一些代码,但它没有给我正确的输出。

这是我尝试过的。

尝试了代码1:

private byte[] rotateYUV420Degree90(byte[] data, int imageWidth, int imageHeight)
    {
        byte[] yuv = new byte[imageWidth * imageHeight * 3 / 2];
        // Rotate the Y luma
        int i = 0;
        for (int x = 0; x < imageWidth; x++)
        {
            for (int y = imageHeight - 1; y >= 0; y--)
            {
                yuv[i] = data[y * imageWidth + x];
                i++;
            }
        }
        // Rotate the U and V color components 
        i = imageWidth * imageHeight * 3 / 2 - 1;
        for (int x = imageWidth - 1; x > 0; x = x - 2)
        {
            for (int y = 0; y < imageHeight / 2; y++)
            {
                yuv[i] = data[(imageWidth * imageHeight) + (y * imageWidth) + x];
                i--;
                yuv[i] = data[(imageWidth * imageHeight) + (y * imageWidth) + (x - 1)];
                i--;
            }
        }
        return yuv;
    }

尝试过代码2:

   public static byte[] rotateNV21(byte[] input, byte[] output, int width, int height, int rotation)
    {
        Boolean swap = (rotation == 90 || rotation == 270);
        Boolean yflip = (rotation == 90 || rotation == 180);
        Boolean xflip = (rotation == 270 || rotation == 180);
        for (int x = 0; x < width; x++)
        {
            for (int y = 0; y < height; y++)
            {
                int xo = x, yo = y;
                int w = width, h = height;
                int xi = xo, yi = yo;
                if (swap)
                {
                    xi = w * yo / h;
                    yi = h * xo / w;
                }
                if (yflip)
                {
                    yi = h - yi - 1;
                }
                if (xflip)
                {
                    xi = w - xi - 1;
                }
                output[w * yo + xo] = input[w * yi + xi];
                int fs = w * h;
                int qs = (fs >> 2);
                xi = (xi >> 1);
                yi = (yi >> 1);
                xo = (xo >> 1);
                yo = (yo >> 1);
                w = (w >> 1);
                h = (h >> 1);
                // adjust for interleave here
                int ui = fs + (w * yi + xi) * 2;
                int uo = fs + (w * yo + xo) * 2;
                // and here
                int vi = ui + 1;
                int vo = uo + 1;
                output[uo] = input[ui];
                output[vo] = input[vi];
               // return output;
            }
        }
        return output;
    }

尝试了代码3:

 public static void rotateY12toYUV420(byte[] input, byte[] output, int width, int height, int rotation)
    {
        Boolean swap = (rotation == 90 || rotation == 270);
        Boolean flip = (rotation == 90 || rotation == 180);
        for (int x = 0; x < width; x++)
        {
            for (int y = 0; y < height; y++)
            {


                int xo = x, yo = y;
                int w = width, h = height;
                int xi = xo, yi = yo;
                if (swap)
                {
                    xi = w * yo / h;
                    yi = h * xo / w;
                }
                if (flip)
                {
                    xi = w - xi - 1;
                    yi = h - yi - 1;
                }
                output[w * yo + xo] = input[w * yi + xi];
                int fs = w * h;
                int qs = (fs >> 2);
                xi = (xi >> 1);
                yi = (yi >> 1);
                xo = (xo >> 1);
                yo = (yo >> 1);
                w = (w >> 1);
                int ui = fs + w * yi + xi;
                int uo = fs + w * yo + xo;
                int vi = qs + ui;
                int vo = qs + uo;
                output[uo] = input[vi];
                output[vo] = input[ui];
            }
        }
    }

尝试了代码4:

        public Bitmap rotateImage(int angle, Bitmap bitmapSrc)
    {
        Matrix matrix = new Matrix();
        matrix.postRotate(angle);
        return Bitmap.createBitmap(bitmapSrc, 0, 0,
            bitmapSrc.getWidth(), bitmapSrc.getHeight(), matrix, true);
    }

请帮忙。 谢谢。

最佳答案

Android.Graphics.Bitmap bmp = Android.Graphics.BitmapFactory.DecodeByteArray(imageData, 0, imageData.Length);
            Android.Graphics.Matrix matrix = new Android.Graphics.Matrix();
            matrix.PostRotate(90);
            bmp = Android.Graphics.Bitmap.CreateBitmap(bmp, 0, 0, bmp.Width, bmp.Height, matrix, true);

            MemoryStream ms = new MemoryStream();
            bmp.Compress(Android.Graphics.Bitmap.CompressFormat.Jpeg, 100, ms);
            File.WriteAllBytes(filePath, ms.ToArray());

这段代码对我有用。

关于android - 如何在xamarin android中旋转YuvImage,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44321846/

相关文章:

android - 我怎么知道我的标记是否在街上

java - 调整 fragment 的尺寸

java - jframe 中的多个 'imageviews'

python - 使用带有图像标签的 csv 文件从文件夹中获取特定图像

Swift SpriteKit 在 x 轴旋转节点

rotation - 如何确定 gnuplot 中轴的纵横比?

java - IndexOutOfBoundException 在 recyclerview 上检测到不一致

android - 将 View 添加到 RelativeLayout 会更改其大小

iphone - 如何使用 GeoLocation 在 map 上定位标记?

c++ - 如何通过在for循环中旋转一个方向来获取采样点?