예제 #1
0
        /// <summary>
        /// Takes a .vr.jpg file, extracts the individual eye images and recombine them into a full omni-stereo image.
        /// </summary>
        public static Bitmap CreateStereoEquirectangular(string filename, EyeImageGeometry geometry = EyeImageGeometry.OverUnder, bool fillPoles = true, int maxWidth = 0)
        {
            var       xmpDirectories = VrJpegMetadataReader.ReadMetadata(filename);
            GPanorama pano           = new GPanorama(xmpDirectories.ToList());

            Bitmap left  = new Bitmap(filename);
            Bitmap right = ExtractRightEye(pano);

            if (right == null)
            {
                left.Dispose();
                return(null);
            }

            Bitmap leftEquir  = Equirectangularize(left, pano, fillPoles, maxWidth);
            Bitmap rightEquir = Equirectangularize(right, pano, fillPoles, maxWidth);
            Bitmap composite  = ComposeEyes(leftEquir, rightEquir, geometry);

            left.Dispose();
            right.Dispose();
            leftEquir.Dispose();
            rightEquir.Dispose();

            return(composite);
        }
예제 #2
0
        /// <summary>
        /// Extracts the embedded image from the panorama and returns it as a Bitmap.
        /// Note: the left eye can be extracted simply by loading the original file into a regular Bitmap.
        /// </summary>
        public static Bitmap ExtractRightEye(GPanorama pano)
        {
            if (pano.ImageData == null)
            {
                return(null);
            }

            Bitmap bmp = null;

            using (var stream = new MemoryStream(pano.ImageData))
                bmp = new Bitmap(stream);

            return(bmp);
        }
예제 #3
0
        /// <summary>
        /// Takes a single eye Bitmap and creates a fully spherical equirectangular image,
        /// with the pano painted at the correct latitude-longitude.
        /// Optionally fills in the poles.
        /// </summary>
        public static Bitmap Equirectangularize(Bitmap bitmap, GPanorama pano, bool fillPoles = true, int maxWidth = 0)
        {
            if (bitmap == null)
            {
                return(null);
            }

            Rectangle crop = new Rectangle(pano.PanoCroppedAreaLeftPixels, pano.PanoCroppedAreaTopPixels, pano.PanoCroppedAreaImageWidthPixels, pano.PanoCroppedAreaImageHeightPixels);

            int imgWidth  = pano.PanoFullPanoWidthPixels;
            int imgHeight = pano.PanoFullPanoHeightPixels;

            if (maxWidth > 0 && imgWidth > maxWidth)
            {
                float ratio = (float)maxWidth / imgWidth;

                imgWidth  = maxWidth;
                imgHeight = imgWidth / 2;

                // In case of subpixel coordinate, expand the rectangle.
                crop = new Rectangle((int)Math.Floor(crop.Left * ratio), (int)Math.Floor(crop.Top * ratio), (int)Math.Ceiling(crop.Width * ratio), (int)Math.Ceiling(crop.Height * ratio));
            }

            Bitmap   result = new Bitmap(imgWidth, imgHeight, bitmap.PixelFormat);
            Graphics g      = Graphics.FromImage(result);

            g.DrawImage(bitmap, crop);
            g.Dispose();

            if (fillPoles)
            {
                PoleFiller.Fill(result, crop);
            }

            return(result);
        }