Exemple #1
0
        void MakeAlphaTestImage(LocalLoadResult loadResult)
        {
            if (loadResult.bitmap == null)
            {
                return;
            }

            int width  = loadResult.bitmap.Width;
            int height = loadResult.bitmap.Height;

            loadResult.alphatestWidth  = width;
            loadResult.alphatestHeight = height;
            for (int y = 0; y < height; y++)
            {
                for (int x = 0; x < width; x++)
                {
                    if (loadResult.bitmap.GetPixel(x, y).A == 0)
                    {
                        if (loadResult.alphatest == null)
                        {
                            loadResult.alphatest = new BitArray(width * height, true);
                        }
                        loadResult.alphatest.Set(x + y * width, false);
                    }
                }
            }
        }
        unsafe void MakeAlphaTestImage(LocalLoadResult loadResult)
        {
            if (loadResult.bitmap == null)
            {
                return;
            }

            int width  = loadResult.bitmap.Width;
            int height = loadResult.bitmap.Height;

            loadResult.alphatestWidth  = width;
            loadResult.alphatestHeight = height;

            BitmapData  bmpdata = loadResult.bitmap.LockBits(new Rectangle(0, 0, loadResult.bitmap.Size.Width, loadResult.bitmap.Size.Height), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
            PixelColor *pixels  = (PixelColor *)(bmpdata.Scan0.ToPointer());

            for (int y = 0; y < height; y++)
            {
                PixelColor *line = pixels + y * width;
                for (int x = 0; x < width; x++)
                {
                    if (line[x].a == 0)
                    {
                        if (loadResult.alphatest == null)
                        {
                            loadResult.alphatest = new BitArray(width * height, true);
                        }
                        loadResult.alphatest.Set(x + y * width, false);
                    }
                }
            }

            loadResult.bitmap.UnlockBits(bmpdata);
        }
Exemple #3
0
        // Loads the image directly. This is needed by the background loader for some patches.
        public Bitmap LocalGetBitmap()
        {
            // Note: if this turns out to be too slow, do NOT try to make it use GetBitmap or bitmap.
            // Create a cache for the local background loader thread instead.

            LocalLoadResult result = LocalLoadImage();

            if (result.messages.Any(x => x.Type == ErrorType.Error))
            {
                return(Properties.Resources.Failed);
            }
            ConvertImageFormat(result);
            return(result.bitmap);
        }
Exemple #4
0
        const int MAX_PREVIEW_SIZE = 256; //mxd

        // This makes a preview for the given image and updates the image settings
        private void MakeImagePreview(LocalLoadResult loadResult)
        {
            if (loadResult.bitmap == null)
            {
                return;
            }

            Bitmap image = loadResult.bitmap;
            Bitmap preview;

            int imagewidth  = image.Width;
            int imageheight = image.Height;

            // Determine preview size
            float scalex        = (imagewidth > MAX_PREVIEW_SIZE) ? (MAX_PREVIEW_SIZE / (float)imagewidth) : 1.0f;
            float scaley        = (imageheight > MAX_PREVIEW_SIZE) ? (MAX_PREVIEW_SIZE / (float)imageheight) : 1.0f;
            float scale         = Math.Min(scalex, scaley);
            int   previewwidth  = (int)(imagewidth * scale);
            int   previewheight = (int)(imageheight * scale);

            if (previewwidth < 1)
            {
                previewwidth = 1;
            }
            if (previewheight < 1)
            {
                previewheight = 1;
            }

            //mxd. Expected and actual image sizes and format match?
            if (previewwidth == imagewidth && previewheight == imageheight && image.PixelFormat == PixelFormat.Format32bppArgb)
            {
                preview = new Bitmap(image);
            }
            else
            {
                // Make new image
                preview = new Bitmap(previewwidth, previewheight, PixelFormat.Format32bppArgb);
                Graphics g = Graphics.FromImage(preview);
                g.PageUnit = GraphicsUnit.Pixel;
                //g.CompositingQuality = CompositingQuality.HighQuality; //mxd
                g.InterpolationMode = InterpolationMode.NearestNeighbor;
                //g.SmoothingMode = SmoothingMode.HighQuality; //mxd
                g.PixelOffsetMode = PixelOffsetMode.None;
                //g.Clear(Color.Transparent); //mxd

                // Draw image onto atlas
                Rectangle  atlasrect = new Rectangle(0, 0, previewwidth, previewheight);
                RectangleF imgrect   = General.MakeZoomedRect(new Size(imagewidth, imageheight), atlasrect);
                if (imgrect.Width < 1.0f)
                {
                    imgrect.X    -= 0.5f - imgrect.Width * 0.5f;
                    imgrect.Width = 1.0f;
                }
                if (imgrect.Height < 1.0f)
                {
                    imgrect.Y     -= 0.5f - imgrect.Height * 0.5f;
                    imgrect.Height = 1.0f;
                }
                g.DrawImage(image, imgrect);
                g.Dispose();
            }

            loadResult.preview = preview;
        }
Exemple #5
0
        void ConvertImageFormat(LocalLoadResult loadResult)
        {
            // Bitmap loaded successfully?
            Bitmap bitmap = loadResult.bitmap;

            if (bitmap != null)
            {
                // Bitmap has incorrect format?
                if (bitmap.PixelFormat != PixelFormat.Format32bppArgb)
                {
                    //General.ErrorLogger.Add(ErrorType.Warning, "Image '" + name + "' does not have A8R8G8B8 pixel format. Conversion was needed.");
                    Bitmap oldbitmap = bitmap;
                    try
                    {
                        // Convert to desired pixel format
                        bitmap = new Bitmap(oldbitmap.Size.Width, oldbitmap.Size.Height, PixelFormat.Format32bppArgb);
                        Graphics g = Graphics.FromImage(bitmap);
                        g.PageUnit           = GraphicsUnit.Pixel;
                        g.CompositingQuality = CompositingQuality.HighQuality;
                        g.InterpolationMode  = InterpolationMode.NearestNeighbor;
                        g.SmoothingMode      = SmoothingMode.None;
                        g.PixelOffsetMode    = PixelOffsetMode.None;
                        g.Clear(Color.Transparent);
                        g.DrawImage(oldbitmap, 0, 0, oldbitmap.Size.Width, oldbitmap.Size.Height);
                        g.Dispose();
                        oldbitmap.Dispose();
                    }
                    catch (Exception e)
                    {
                        bitmap = oldbitmap;
                        loadResult.messages.Add(new LogMessage(ErrorType.Warning, "Cannot lock image \"" + name + "\" for pixel format conversion. The image may not be displayed correctly.\n" + e.GetType().Name + ": " + e.Message));
                    }
                }

                // This applies brightness correction on the image
                if (usecolorcorrection)
                {
                    BitmapData bmpdata = null;

                    try
                    {
                        // Try locking the bitmap
                        bmpdata = bitmap.LockBits(new Rectangle(0, 0, bitmap.Size.Width, bitmap.Size.Height), ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);
                    }
                    catch (Exception e)
                    {
                        loadResult.messages.Add(new LogMessage(ErrorType.Warning, "Cannot lock image \"" + name + "\" for color correction. The image may not be displayed correctly.\n" + e.GetType().Name + ": " + e.Message));
                    }

                    // Bitmap locked?
                    if (bmpdata != null)
                    {
                        // Apply color correction
                        PixelColor *pixels = (PixelColor *)(bmpdata.Scan0.ToPointer());
                        General.Colors.ApplyColorCorrection(pixels, bmpdata.Width * bmpdata.Height);
                        bitmap.UnlockBits(bmpdata);
                    }
                }
            }
            else
            {
                // Loading failed
                // We still mark the image as ready so that it will
                // not try loading again until Reload Resources is used
                bitmap = new Bitmap(Properties.Resources.Failed);
            }

            if (bitmap != null)
            {
                width  = bitmap.Size.Width;
                height = bitmap.Size.Height;

                // Do we still have to set a scale?
                if ((scale.x == 0.0f) && (scale.y == 0.0f))
                {
                    if ((General.Map != null) && (General.Map.Config != null))
                    {
                        scale.x = General.Map.Config.DefaultTextureScale;
                        scale.y = General.Map.Config.DefaultTextureScale;
                    }
                    else
                    {
                        scale.x = 1.0f;
                        scale.y = 1.0f;
                    }
                }

                if (!loadfailed)
                {
                    //mxd. Check translucency and calculate average color?
                    if (General.Map != null && General.Map.Data != null && General.Map.Data.GlowingFlats != null &&
                        General.Map.Data.GlowingFlats.ContainsKey(longname) &&
                        General.Map.Data.GlowingFlats[longname].CalculateTextureColor)
                    {
                        BitmapData bmpdata = null;
                        try
                        {
                            bmpdata = bitmap.LockBits(new Rectangle(0, 0, bitmap.Size.Width, bitmap.Size.Height), ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);
                        }
                        catch (Exception e)
                        {
                            loadResult.messages.Add(new LogMessage(ErrorType.Error, "Cannot lock image \"" + this.filepathname + "\" for glow color calculation. " + e.GetType().Name + ": " + e.Message));
                        }

                        if (bmpdata != null)
                        {
                            PixelColor *pixels    = (PixelColor *)(bmpdata.Scan0.ToPointer());
                            int         numpixels = bmpdata.Width * bmpdata.Height;
                            uint        r         = 0;
                            uint        g         = 0;
                            uint        b         = 0;

                            for (PixelColor *cp = pixels + numpixels - 1; cp >= pixels; cp--)
                            {
                                r += cp->r;
                                g += cp->g;
                                b += cp->b;

                                // Also check alpha
                                if (cp->a > 0 && cp->a < 255)
                                {
                                    istranslucent = true;
                                }
                                else if (cp->a == 0)
                                {
                                    ismasked = true;
                                }
                            }

                            // Update glow data
                            int br = (int)(r / numpixels);
                            int bg = (int)(g / numpixels);
                            int bb = (int)(b / numpixels);

                            int max = Math.Max(br, Math.Max(bg, bb));

                            // Black can't glow...
                            if (max == 0)
                            {
                                General.Map.Data.GlowingFlats.Remove(longname);
                            }
                            else
                            {
                                // That's how it's done in GZDoom (and I may be totally wrong about this)
                                br = Math.Min(255, br * 153 / max);
                                bg = Math.Min(255, bg * 153 / max);
                                bb = Math.Min(255, bb * 153 / max);

                                General.Map.Data.GlowingFlats[longname].Color = new PixelColor(255, (byte)br, (byte)bg, (byte)bb);
                                General.Map.Data.GlowingFlats[longname].CalculateTextureColor = false;
                                if (!General.Map.Data.GlowingFlats[longname].Fullbright)
                                {
                                    General.Map.Data.GlowingFlats[longname].Brightness = (br + bg + bb) / 3;
                                }
                            }

                            // Release the data
                            bitmap.UnlockBits(bmpdata);
                        }
                    }
                    //mxd. Check if the texture is translucent
                    else
                    {
                        BitmapData bmpdata = null;
                        try
                        {
                            bmpdata = bitmap.LockBits(new Rectangle(0, 0, bitmap.Size.Width, bitmap.Size.Height), ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);
                        }
                        catch (Exception e)
                        {
                            loadResult.messages.Add(new LogMessage(ErrorType.Error, "Cannot lock image \"" + this.filepathname + "\" for translucency check. " + e.GetType().Name + ": " + e.Message));
                        }

                        if (bmpdata != null)
                        {
                            PixelColor *pixels    = (PixelColor *)(bmpdata.Scan0.ToPointer());
                            int         numpixels = bmpdata.Width * bmpdata.Height;

                            for (PixelColor *cp = pixels + numpixels - 1; cp >= pixels; cp--)
                            {
                                // Check alpha
                                if (cp->a > 0 && cp->a < 255)
                                {
                                    istranslucent = true;
                                }
                                else if (cp->a == 0)
                                {
                                    ismasked = true;
                                }
                            }

                            // Release the data
                            bitmap.UnlockBits(bmpdata);
                        }
                    }
                }
            }

            loadResult.bitmap = bitmap;
        }
Exemple #6
0
        // This loads the image
        protected void LoadImage(bool notify)
        {
            if (imagestate == ImageLoadState.Ready && previewstate != ImageLoadState.Loading)
            {
                return;
            }

            // Do the loading
            LocalLoadResult loadResult = LocalLoadImage();

            ConvertImageFormat(loadResult);
            MakeImagePreview(loadResult);
            MakeAlphaTestImage(loadResult);

            // Save memory by disposing the original image immediately if we only used it to load a preview image
            bool onlyPreview = false;

            if (imagestate != ImageLoadState.Loading)
            {
                loadResult.bitmap?.Dispose();
                loadResult.bitmap = null;
                onlyPreview       = true;
            }

            General.MainWindow.RunOnUIThread(() =>
            {
                if (imagestate == ImageLoadState.Loading && !onlyPreview)
                {
                    // Log errors and warnings
                    foreach (LogMessage message in loadResult.messages)
                    {
                        General.ErrorLogger.Add(message.Type, message.Text);
                    }

                    if (loadResult.messages.Any(x => x.Type == ErrorType.Error))
                    {
                        loadfailed = true;
                    }

                    loadedbitmap?.Dispose();
                    texture?.Dispose();
                    imagestate      = ImageLoadState.Ready;
                    loadedbitmap    = loadResult.bitmap;
                    alphatest       = loadResult.alphatest;
                    alphatestWidth  = loadResult.alphatestWidth;
                    alphatestHeight = loadResult.alphatestHeight;

                    if (loadResult.uiThreadWork != null)
                    {
                        loadResult.uiThreadWork();
                    }
                }
                else
                {
                    loadResult.bitmap?.Dispose();
                }

                if (previewstate == ImageLoadState.Loading)
                {
                    previewbitmap?.Dispose();
                    previewstate  = ImageLoadState.Ready;
                    previewbitmap = loadResult.preview;
                }
                else
                {
                    loadResult.preview?.Dispose();
                }
            });

            // Notify the main thread about the change so that sectors can update their buffers
            if (notify)
            {
                if (this is SpriteImage || this is VoxelImage)
                {
                    General.MainWindow.SpriteDataLoaded(this.Name);
                }
                else
                {
                    General.MainWindow.ImageDataLoaded(this.name);
                }
            }
        }