Ejemplo n.º 1
0
        public ExportDialog(Models.Models models, string filename, ImageLoader.ImageFormat defaultPixelFormat, ExportModel.FileFormat format)
        {
            models.Export.Init(filename, defaultPixelFormat, format);
            viewModel   = new ExportViewModel(models);
            DataContext = viewModel;

            InitializeComponent();
        }
Ejemplo n.º 2
0
        // initializes the export model for a new export
        public void Init(string filename, ImageLoader.ImageFormat pixelFormat, FileFormat fileFormat)
        {
            Filename   = filename;
            FileType   = fileFormat;
            HasQuality = false;

            var supportedFormats = new List <DisplayedFormat>();

            switch (fileFormat)
            {
            case FileFormat.Png:
                supportedFormats.Add(new DisplayedFormat(new ImageLoader.ImageFormat(PixelFormat.Red, PixelType.UnsignedByte, true), "Red"));
                supportedFormats.Add(new DisplayedFormat(new ImageLoader.ImageFormat(PixelFormat.Green, PixelType.UnsignedByte, true), "Green"));
                supportedFormats.Add(new DisplayedFormat(new ImageLoader.ImageFormat(PixelFormat.Blue, PixelType.UnsignedByte, true), "Blue"));
                supportedFormats.Add(new DisplayedFormat(new ImageLoader.ImageFormat(PixelFormat.Alpha, PixelType.UnsignedByte, true), "Alpha"));
                supportedFormats.Add(new DisplayedFormat(new ImageLoader.ImageFormat(PixelFormat.Rg, PixelType.UnsignedByte, true), "RG"));
                supportedFormats.Add(new DisplayedFormat(new ImageLoader.ImageFormat(PixelFormat.Rgb, PixelType.UnsignedByte, true), "RGB"));
                supportedFormats.Add(new DisplayedFormat(new ImageLoader.ImageFormat(PixelFormat.Rgba, PixelType.UnsignedByte, true), "RGBA"));
                break;

            case FileFormat.Dds:
            case FileFormat.Ktx:
                for (int i = (int)GliFormat.FORMAT_FIRST; i <= (int)GliFormat.LAST; ++i)
                {
                    var format = (GliFormat)i;
                    if (!Gli.IsSupported(format))
                    {
                        continue;
                    }

                    var imgf = new ImageLoader.ImageFormat(format);
                    // TODO support compressed format as well
                    if (!imgf.IsCompressed)
                    {
                        supportedFormats.Add(new DisplayedFormat(imgf, format.ToString()));
                    }
                }
                break;

            case FileFormat.Ktx2:
                // TODO: Implement.
                break;

            case FileFormat.Jpg:
                supportedFormats.Add(new DisplayedFormat(new ImageLoader.ImageFormat(PixelFormat.Red, PixelType.UnsignedByte, true), "Red"));
                supportedFormats.Add(new DisplayedFormat(new ImageLoader.ImageFormat(PixelFormat.Green, PixelType.UnsignedByte, true), "Green"));
                supportedFormats.Add(new DisplayedFormat(new ImageLoader.ImageFormat(PixelFormat.Blue, PixelType.UnsignedByte, true), "Blue"));
                supportedFormats.Add(new DisplayedFormat(new ImageLoader.ImageFormat(PixelFormat.Alpha, PixelType.UnsignedByte, true), "Alpha"));
                supportedFormats.Add(new DisplayedFormat(new ImageLoader.ImageFormat(PixelFormat.Rgb, PixelType.UnsignedByte, true), "RGB"));
                HasQuality = true;
                MinQuality = 1;
                MaxQuality = 100;
                Quality    = Properties.Settings.Default.JpgQuality;
                break;

            case FileFormat.Bmp:
                supportedFormats.Add(new DisplayedFormat(new ImageLoader.ImageFormat(PixelFormat.Red, PixelType.UnsignedByte, true), "Red"));
                supportedFormats.Add(new DisplayedFormat(new ImageLoader.ImageFormat(PixelFormat.Green, PixelType.UnsignedByte, true), "Green"));
                supportedFormats.Add(new DisplayedFormat(new ImageLoader.ImageFormat(PixelFormat.Blue, PixelType.UnsignedByte, true), "Blue"));
                supportedFormats.Add(new DisplayedFormat(new ImageLoader.ImageFormat(PixelFormat.Alpha, PixelType.UnsignedByte, true), "Alpha"));
                supportedFormats.Add(new DisplayedFormat(new ImageLoader.ImageFormat(PixelFormat.Rg, PixelType.UnsignedByte, true), "RG"));
                supportedFormats.Add(new DisplayedFormat(new ImageLoader.ImageFormat(PixelFormat.Rgb, PixelType.UnsignedByte, true), "RGB"));
                break;

            case FileFormat.Hdr:
            case FileFormat.Pfm:
                supportedFormats.Add(new DisplayedFormat(new ImageLoader.ImageFormat(PixelFormat.Red, PixelType.Float, false), "Red"));
                supportedFormats.Add(new DisplayedFormat(new ImageLoader.ImageFormat(PixelFormat.Green, PixelType.Float, false), "Green"));
                supportedFormats.Add(new DisplayedFormat(new ImageLoader.ImageFormat(PixelFormat.Blue, PixelType.Float, false), "Blue"));
                supportedFormats.Add(new DisplayedFormat(new ImageLoader.ImageFormat(PixelFormat.Alpha, PixelType.Float, false), "Alpha"));
                supportedFormats.Add(new DisplayedFormat(new ImageLoader.ImageFormat(PixelFormat.Rgb, PixelType.Float, false), "RGB"));
                break;
            }

            // select preferred texture format
            TexFormat = supportedFormats.Last();
            foreach (var df in supportedFormats)
            {
                if (df.Format.Equals(pixelFormat))
                {
                    TexFormat = df;
                }
            }

            SupportedFormats = supportedFormats;

            Layer  = displayModel.ActiveLayer;
            Mipmap = displayModel.ActiveMipmap;
        }
Ejemplo n.º 3
0
 public DisplayedFormat(ImageLoader.ImageFormat format, string displayedName)
 {
     Format        = format;
     DisplayedName = displayedName;
 }
Ejemplo n.º 4
0
        public void Execute(object parameter)
        {
            if (models.Images.NumImages == 0)
            {
                return;
            }

            // make sure only one image is visible
            if (models.Equations.NumVisible != 1)
            {
                App.ShowInfoDialog(models.App.Window, "Exactly one image equation should be visible when exporting.");
                return;
            }

            // get active final image
            var equationId       = models.Equations.GetFirstVisible();
            var firstImageId     = models.Equations.Get(equationId).ColorFormula.FirstImageId;
            var proposedFilename = firstImageId < models.Images.NumImages ?
                                   System.IO.Path.GetFileNameWithoutExtension(models.Images.GetFilename(firstImageId)) : "";

            // open save file dialog
            var sfd = new SaveFileDialog
            {
                Filter           = "PNG (*.png)|*.png|BMP (*.bmp)|*.bmp|JPEG (*.jpg)|*.jpg|HDR (*.hdr)|*.hdr|Portable float map (*.pfm)|*.pfm|Khronos Texture (*.ktx)|*.ktx|Khronos Texture (*.ktx2)|*.ktx2|DirectDraw Surface (*.dds)|*.dds",
                InitialDirectory = Properties.Settings.Default.ExportPath,
                FileName         = proposedFilename
            };

            if (sfd.ShowDialog() != true)
            {
                return;
            }

            Properties.Settings.Default.ExportPath = System.IO.Path.GetDirectoryName(sfd.FileName);

            // obtain file format
            var format = ExportModel.FileFormat.Png;

            if (sfd.FileName.EndsWith(".bmp"))
            {
                format = ExportModel.FileFormat.Bmp;
            }
            else if (sfd.FileName.EndsWith(".hdr"))
            {
                format = ExportModel.FileFormat.Hdr;
            }
            else if (sfd.FileName.EndsWith(".pfm"))
            {
                format = ExportModel.FileFormat.Pfm;
            }
            else if (sfd.FileName.EndsWith(".jpg"))
            {
                format = ExportModel.FileFormat.Jpg;
            }
            else if (sfd.FileName.EndsWith(".ktx"))
            {
                format = ExportModel.FileFormat.Ktx;
            }
            else if (sfd.FileName.EndsWith(".ktx2"))
            {
                format = ExportModel.FileFormat.Ktx2;
            }
            else if (sfd.FileName.EndsWith(".dds"))
            {
                format = ExportModel.FileFormat.Dds;
            }

            var texFormat = new ImageLoader.ImageFormat(PixelFormat.Rgb, PixelType.UnsignedByte, true);

            switch (format)
            {
            case ExportModel.FileFormat.Png:
            case ExportModel.FileFormat.Bmp:
            case ExportModel.FileFormat.Jpg:
                if (models.Images.IsAlpha && format == ExportModel.FileFormat.Png)
                {
                    texFormat.ExternalFormat = PixelFormat.Rgba;
                }
                if (models.Images.IsGrayscale)
                {
                    texFormat.ExternalFormat = PixelFormat.Red;
                }
                break;

            case ExportModel.FileFormat.Hdr:
            case ExportModel.FileFormat.Pfm:
                texFormat = new ImageLoader.ImageFormat(PixelFormat.Rgb, PixelType.Float, false);
                if (models.Images.IsGrayscale)
                {
                    texFormat.ExternalFormat = PixelFormat.Red;
                }
                break;

            case ExportModel.FileFormat.Ktx:
            case ExportModel.FileFormat.Ktx2:
            case ExportModel.FileFormat.Dds:
                // load default format from settings
                if (Enum.TryParse <GliFormat>(Properties.Settings.Default.GliFormat, out var fmt))
                {
                    texFormat = new ImageLoader.ImageFormat(fmt);
                }
                else
                {
                    texFormat = new ImageLoader.ImageFormat(GliFormat.RGB8_SRGB_PACK8);
                }
                break;
            }

            models.Export.IsExporting = true;
            // open export dialog
            var dia = new ExportDialog(models, sfd.FileName, texFormat, format);

            dia.Owner   = models.App.Window;
            dia.Closed += (sender, args) =>
            {
                models.Export.IsExporting = false;

                // save gli format if present
                var fmt = models.Export.TexFormat.Format;
                if (fmt.HasGliFormat)
                {
                    Properties.Settings.Default.GliFormat = fmt.GliFormat.ToString();
                }

                if (!dia.ExportResult)
                {
                    return;
                }

                var info = models.Export;

                models.GlContext.Enable();
                try
                {
                    // obtain data from gpu
                    var texture = models.FinalImages.Get(equationId).Texture;
                    if (texture == null)
                    {
                        throw new Exception("texture is not computed");
                    }

                    if (info.FileType == ExportModel.FileFormat.Ktx || info.FileType == ExportModel.FileFormat.Ktx2 || info.FileType == ExportModel.FileFormat.Dds)
                    {
                        SaveMultipleLevel(info, texture);
                    }
                    else
                    {
                        SaveSingleLevel(info, texture);
                    }
                }
                catch (Exception e)
                {
                    App.ShowErrorDialog(models.App.Window, e.Message);
                }
                finally
                {
                    models.GlContext.Disable();
                }
            };

            dia.Show();
        }
Ejemplo n.º 5
0
        /// <summary>
        /// reads (sub) data from a single image layer and a single image mipmap with the specified format and type
        /// </summary>
        /// <param name="layer">image layer</param>
        /// <param name="mipmap">image mipmap</param>
        /// <param name="format">destination format</param>
        /// <param name="type">destination type</param>
        /// <param name="toSrgb">indicates if data should be converted into srgb space</param>
        /// <param name="useCropping">indicates if the source image should be cropped</param>
        /// <param name="xOffset">if useCropping: x pixel offset</param>
        /// <param name="yOffset">if useCropping: y pixel offset</param>
        /// <param name="width">if useCropping: width of destination image. Will be set to the exported image width</param>
        /// <param name="height">if useCropping: height of destination image. Will be set to the exported image height</param>
        /// <param name="exportShader">shader required for srgb conversion and cropping</param>
        /// <param name="bufferSize"> Expected size of buffer in bytes. If bufferSize = 0 the buffer size will be calculated based the pixel type size times the number of pixel components (this only works for simple formats)</param>
        /// <returns></returns>
        public byte[] GetData(int layer, int mipmap, ImageLoader.ImageFormat format, bool useCropping,
                              int xOffset, int yOffset, ref int width, ref int height, PixelExportShader exportShader, int bufferSize = 0)
        {
            Debug.Assert(!format.IsCompressed);

            // retrieve width and height of the mipmap
            GL.BindTexture(TextureTarget.Texture2DArray, id);
            GL.GetTexLevelParameter(TextureTarget.Texture2DArray, mipmap, GetTextureParameter.TextureWidth, out int maxWidth);
            GL.GetTexLevelParameter(TextureTarget.Texture2DArray, mipmap, GetTextureParameter.TextureHeight, out int maxHeight);

            Debug.Assert(layer < nLayer);
            Debug.Assert(mipmap < nMipmaps);
            if (useCropping)
            {
                Debug.Assert(xOffset + width <= maxWidth);
                Debug.Assert(yOffset + height <= maxHeight);
            }
            else
            {
                xOffset = 0;
                yOffset = 0;
                width   = maxWidth;
                height  = maxHeight;
            }


            int bs = bufferSize;

            // try to calculate the buffer size (only for simple formats)
            if (bs == 0)
            {
                bs = width * height * GetPixelTypeSize(format.Type) * GetPixelFormatCount(format.Format);
            }
            byte[] buffer = new byte[bs];

            //if (format.IsSrgb || useCropping)
            // This needs to be used due to some export bug with certain formats (e.g. RGBA4_UNORM_PACK16)
            {
                // create temporary texture and convert data
                var tmpTex = GL.GenTexture();
                GL.BindTexture(TextureTarget.Texture2D, tmpTex);
                GL.TexStorage2D(TextureTarget2d.Texture2D, 1, SizedInternalFormat.Rgba32f, width, height);

                // use crop/srgb shader
                GL.BindImageTexture(exportShader.GetDestinationTextureLocation(), tmpTex, 0, false, 0, TextureAccess.WriteOnly, SizedInternalFormat.Rgba32f);
                BindAsTexture2D(exportShader.GetSourceTextureLocation(), layer, mipmap);

                exportShader.Use(xOffset, yOffset, width, height, format.IsSrgb);

                // obtain data
                GL.BindTexture(TextureTarget.Texture2D, tmpTex);
                GL.GetTexImage(TextureTarget.Texture2D, 0, format.Format, format.Type, buffer);

                // cleanup
                GL.DeleteTexture(tmpTex);
            }
            //else
            //{
            //    // read directly (NOT POSSIBLE DUE TO EXPORT BUG e.g. RGBA4_UNORM_PACK16)
            //    BindAsTexture2D(0, layer, mipmap);
            //    GL.GetTexImage(TextureTarget.Texture2D, 0, format.Format, format.Type, buffer);
            //}

            return(buffer);
        }