Exemple #1
0
 /// <summary>
 /// Fills DFBitmap with specified values.
 /// </summary>
 /// <param name="bitmap">DFBitmap to fill.</param>
 /// <param name="r">Red value.</param>
 /// <param name="g">Green value.</param>
 /// <param name="b">Blue value.</param>
 /// <param name="a">Alpha value.</param>
 static public void Fill(DFBitmap bitmap, byte r, byte g, byte b, byte a)
 {
     // Fill with value and alpha
     for (int pos = 0; pos < bitmap.Data.Length; pos += bitmap.FormatWidth)
     {
         bitmap.Data[pos]     = r;
         bitmap.Data[pos + 1] = g;
         bitmap.Data[pos + 2] = b;
         bitmap.Data[pos + 3] = a;
     }
 }
        /// <summary>
        /// Creates a clone of a DFBitmap.
        /// </summary>
        /// <param name="bitmap">DFBitmap source.</param>
        /// <returns>Cloned DFBitmap.</returns>
        public static DFBitmap CloneDFBitmap(DFBitmap bitmap)
        {
            // Create destination bitmap to receive normal image
            DFBitmap newBitmap = new DFBitmap();
            newBitmap.Width = bitmap.Width;
            newBitmap.Height = bitmap.Height;
            newBitmap.Data = new byte[bitmap.Data.Length];
            bitmap.Data.CopyTo(newBitmap.Data, 0);

            return newBitmap;
        }
Exemple #3
0
        /// <summary>
        /// Gets pixel DFColor from DFBitmap.
        /// </summary>
        /// <param name="bitmap">DFBitmap.</param>
        /// <param name="x">X position.</param>
        /// <param name="y">Y position.</param>
        /// <returns>DFColor.</returns>
        static public DFColor GetPixel(DFBitmap bitmap, int x, int y)
        {
            DFColor color  = new DFColor();
            int     srcPos = y * bitmap.Stride + x * bitmap.FormatWidth;

            color.r = bitmap.Data[srcPos++];
            color.g = bitmap.Data[srcPos++];
            color.b = bitmap.Data[srcPos++];
            color.a = bitmap.Data[srcPos++];

            return(color);
        }
        /// <summary>
        /// Creates a clone of a DFBitmap.
        /// </summary>
        /// <param name="bitmap">DFBitmap source.</param>
        /// <returns>Cloned DFBitmap.</returns>
        static public DFBitmap CloneDFBitmap(DFBitmap bitmap)
        {
            // Create destination bitmap to receive normal image
            DFBitmap newBitmap = new DFBitmap();

            newBitmap.Width  = bitmap.Width;
            newBitmap.Height = bitmap.Height;
            newBitmap.Data   = new byte[bitmap.Data.Length];
            bitmap.Data.CopyTo(newBitmap.Data, 0);

            return(newBitmap);
        }
        /// <summary>
        /// Creates a clone of a DFBitmap.
        /// </summary>
        /// <param name="bitmap">DFBitmap source.</param>
        /// <param name="cloneData">True to clone data.</param>
        /// <returns>Cloned DFBitmap.</returns>
        public static DFBitmap CloneDFBitmap(DFBitmap bitmap, bool cloneData = true)
        {
            // Create destination bitmap to receive normal image
            DFBitmap newBitmap = new DFBitmap();
            newBitmap.Width = bitmap.Width;
            newBitmap.Height = bitmap.Height;
            newBitmap.Data = new byte[bitmap.Data.Length];
            newBitmap.Palette = bitmap.Palette;

            // Clone data
            if (cloneData)
                bitmap.Data.CopyTo(newBitmap.Data, 0);

            return newBitmap;
        }
        public override DFBitmap GetDFBitmap(int record, int frame)
        {
            DFBitmap result = new DFBitmap();
            if (record == 0 && frame == 0 && managedFile.Length > 0)
            {
                BinaryReader reader = managedFile.GetReader();
                byte[] data = reader.ReadBytes(managedFile.Length);

                DFSize sz = GetSize(0);
                result.Width = sz.Width;
                result.Height = sz.Height;
                result.Data = data;
            }

            return result;
        }
        /// <summary>
        /// Dye supported bitmap image based on dye index and type.
        /// </summary>
        /// <param name="srcBitmap">Source image.</param>
        /// <param name="dye">Dye index.</param>
        /// <param name="target">Dye target.</param>
        /// <returns>New DFBitmap dyed to specified colour.</returns>
        public static DFBitmap ChangeDye(DFBitmap srcBitmap, DyeColors dye, DyeTargets target)
        {
            const int clothingStart = 0x60;
            const int weaponsAndArmorStart = 0x70;

            // Clone bitmap and get colour table for swaps
            DFBitmap dstBitmap = DFBitmap.CloneDFBitmap(srcBitmap, false);
            byte[] swaps = GetDyeColorTable(dye, target);

            // Swaps range is based on target type
            int start;
            switch(target)
            {
                case DyeTargets.Clothing:
                    start = clothingStart;
                    break;
                case DyeTargets.WeaponsAndArmor:
                    start = weaponsAndArmorStart;
                    break;
                default:
                    return dstBitmap;
            }

            // Swap indices start through start + 15 with colour table
            int rowPos;
            for (int y = 0; y < srcBitmap.Height; y++)
            {
                rowPos = y * srcBitmap.Width;
                for (int x = 0; x < srcBitmap.Width; x++)
                {
                    int srcOffset = rowPos + x;
                    byte index = srcBitmap.Data[srcOffset];

                    if (index >= start && index <= start + 0x0f)
                    {
                        int tintOffset = index - start;
                        dstBitmap.Data[srcOffset] = swaps[tintOffset];
                    }
                    else
                    {
                        dstBitmap.Data[srcOffset] = index;
                    }
                }
            }

            return dstBitmap;
        }
        /// <summary>
        /// Creates a clone of a DFBitmap.
        /// </summary>
        /// <param name="bitmap">DFBitmap source.</param>
        /// <param name="cloneData">True to clone data.</param>
        /// <returns>Cloned DFBitmap.</returns>
        static public DFBitmap CloneDFBitmap(DFBitmap bitmap, bool cloneData = true)
        {
            // Create destination bitmap to receive normal image
            DFBitmap newBitmap = new DFBitmap();

            newBitmap.Width   = bitmap.Width;
            newBitmap.Height  = bitmap.Height;
            newBitmap.Data    = new byte[bitmap.Data.Length];
            newBitmap.Palette = bitmap.Palette;

            // Clone data
            if (cloneData)
            {
                bitmap.Data.CopyTo(newBitmap.Data, 0);
            }

            return(newBitmap);
        }
Exemple #9
0
        /// <summary>
        /// Sets pixel in DFBitmap. Colour formats only.
        /// </summary>
        /// <param name="bitmap">DFBitmap.</param>
        /// <param name="x">X position.</param>
        /// <param name="y">Y position.</param>
        /// <param name="colour">Fill colour.</param>
        static public void SetPixel(DFBitmap bitmap, int x, int y, DFColor color)
        {
            int pos = y * bitmap.Stride + x * bitmap.FormatWidth;

            if (bitmap.Format == Formats.RGBA)
            {
                bitmap.Data[pos++] = color.r;
                bitmap.Data[pos++] = color.g;
                bitmap.Data[pos++] = color.b;
                bitmap.Data[pos]   = color.a;
            }
            else if (bitmap.Format == Formats.ARGB)
            {
                bitmap.Data[pos++] = color.a;
                bitmap.Data[pos++] = color.r;
                bitmap.Data[pos++] = color.g;
                bitmap.Data[pos]   = color.b;
            }
        }
        /// <summary>
        /// Changes mask index to another index.
        /// </summary>
        /// <param name="srcBitmap">Source image.</param>
        /// <param name="replaceWith">Index to substitute for mask index.</param>
        /// <returns>New DFBitmap with modified mask.</returns>
        public static DFBitmap ChangeMask(DFBitmap srcBitmap, byte replaceWith = 0)
        {
            const int mask = 0xff;

            // Clone bitmap
            DFBitmap dstBitmap = DFBitmap.CloneDFBitmap(srcBitmap, false);

            // Remove all instances of mask index
            for (int i = 0; i < srcBitmap.Data.Length; i++)
            {
                byte index = srcBitmap.Data[i];
                if (index == mask)
                    dstBitmap.Data[i] = replaceWith;
                else
                    dstBitmap.Data[i] = index;
            }

            return dstBitmap;
        }
Exemple #11
0
        /// <summary>
        /// Constructor to create an empty image of size and format.
        /// </summary>
        /// <param name="width"></param>
        /// <param name="height"></param>
        /// <param name="format"></param>
        public DFManualImage(int width, int height, DFBitmap.Formats format)
        {
            // Create bitmap object
            manualBitmap        = new DFBitmap();
            manualBitmap.Width  = width;
            manualBitmap.Height = height;
            manualBitmap.Format = format;

            // Set stride (1 byte per pixel for indexed, 4 bytes per pixel for all other formats)
            switch (format)
            {
            case DFBitmap.Formats.Indexed:
                manualBitmap.Stride = width;
                break;

            default:
                manualBitmap.Stride = width * 4;
                break;
            }

            // Create bitmap data
            manualBitmap.Data = new byte[manualBitmap.Stride * height];
        }
Exemple #12
0
 /// <summary>
 /// Constructor using a DFBitmap.
 /// </summary>
 /// <param name="dfBitmap">Source DFBitmap object.</param>
 public DFManualImage(DFBitmap dfBitmap)
 {
     manualBitmap = dfBitmap;
 }
Exemple #13
0
 /// <summary>
 /// Default constructor.
 /// </summary>
 public DFManualImage()
 {
     manualBitmap = new DFBitmap();
 }
Exemple #14
0
 /// <summary>
 /// Sets pixel in DFBitmap. Colour formats only.
 /// </summary>
 /// <param name="bitmap">DFBitmap.</param>
 /// <param name="x">X position.</param>
 /// <param name="y">Y position.</param>
 /// <param name="r">Red value.</param>
 /// <param name="g">Green value.</param>
 /// <param name="b">Blue value.</param>
 /// <param name="a">Alpha value.</param>
 static public void SetPixel(DFBitmap bitmap, int x, int y, byte r, byte g, byte b, byte a)
 {
     SetPixel(bitmap, x, y, DFColor.FromRGBA(r, g, b, a));
 }
Exemple #15
0
 /// <summary>
 /// Fills DFBitmap with specified colour.
 /// </summary>
 /// <param name="bitmap">DFBitmap to fill.</param>
 /// <param name="color">Source colour.</param>
 static public void Fill(DFBitmap bitmap, DFColor color)
 {
     Fill(bitmap, color.r, color.g, color.b, color.a);
 }
 /// <summary>
 /// Sets pixel in DFBitmap. Colour formats only.
 /// </summary>
 /// <param name="bitmap">DFBitmap.</param>
 /// <param name="x">X position.</param>
 /// <param name="y">Y position.</param>
 /// <param name="colour">Fill colour.</param>
 public static void SetPixel(DFBitmap bitmap, int x, int y, DFColor color)
 {
     int pos = y * bitmap.Stride + x * bitmap.FormatWidth;
     if (bitmap.Format == Formats.RGBA)
     {
         bitmap.Data[pos++] = color.r;
         bitmap.Data[pos++] = color.g;
         bitmap.Data[pos++] = color.b;
         bitmap.Data[pos] = color.a;
     }
     else if (bitmap.Format == Formats.ARGB)
     {
         bitmap.Data[pos++] = color.a;
         bitmap.Data[pos++] = color.r;
         bitmap.Data[pos++] = color.g;
         bitmap.Data[pos] = color.b;
     }
 }
        /// <summary>
        /// Tint a weapon image based on metal type.
        /// </summary>
        /// <param name="srcBitmap">Source weapon image.</param>
        /// <param name="size">Image size.</param>
        /// <param name="metalType">Metal type for tint.</param>
        public static void TintWeaponImage(DFBitmap srcBitmap, MetalTypes metalType)
        {
            // Must be indexed format
            if (srcBitmap.Format != DFBitmap.Formats.Indexed)
                return;

            byte[] swaps = GetMetalColors(metalType);

            int rowPos;
            for (int y = 0; y < srcBitmap.Height; y++)
            {
                rowPos = y * srcBitmap.Width;
                for (int x = 0; x < srcBitmap.Width; x++)
                {
                    byte index = srcBitmap.Data[rowPos + x];
                    if (index >= 0x70 && index <= 0x7f)
                    {
                        int offset = index - 0x70;
                        srcBitmap.Data[rowPos + x] = swaps[offset];
                    }
                }
            }
        }
        /// <summary>
        /// Resize DFBitmap with a bicubic kernel.
        /// </summary>
        /// <param name="bitmap">DFBitmap source.</param>
        /// <param name="level">MipMap level.</param>
        /// <returns>SnapBitmap mipmap.</returns>
        public static DFBitmap ResizeBicubic(DFBitmap bitmap, int newWidth, int newHeight)
        {
            // Must be colour format
            if (bitmap.Format == DFBitmap.Formats.Indexed)
                return null;

            // Get start size
            int width = bitmap.Width;
            int height = bitmap.Height;

            // Create new bitmap
            DFBitmap newBitmap = new DFBitmap();
            newBitmap.Width = newWidth;
            newBitmap.Height = newHeight;
            newBitmap.Format = bitmap.Format;
            newBitmap.Stride = newBitmap.Width * bitmap.FormatWidth;
            newBitmap.Data = new byte[newBitmap.Stride * newBitmap.Height];

            // Scale factors
            double xFactor = (double)width / newWidth;
            double yFactor = (double)height / newHeight;

            // Coordinates of source points and coefficients
            double ox, oy, dx, dy, k1, k2;
            int ox1, oy1, ox2, oy2;

            // Destination pixel values
            double r, g, b, a;

            // Width and height decreased by 1
            int ymax = height - 1;
            int xmax = width - 1;

            // Bicubic resize
            for (int y = 0; y < newHeight; y++)
            {
                // Y coordinates
                oy = (double)y * yFactor - 0.5f;
                oy1 = (int)oy;
                dy = oy - (double)oy1;

                for (int x = 0; x < newWidth; x++)
                {
                    // X coordinates
                    ox = (double)x * xFactor - 0.5f;
                    ox1 = (int)ox;
                    dx = ox - (double)ox1;

                    // Initial pixel value
                    r = g = b = a = 0;

                    for (int n = -1; n < 3; n++)
                    {
                        // Get Y coefficient
                        k1 = BiCubicKernel(dy - (double)n);

                        oy2 = oy1 + n;
                        if (oy2 < 0)
                            oy2 = 0;
                        if (oy2 > ymax)
                            oy2 = ymax;

                        for (int m = -1; m < 3; m++)
                        {
                            // Get X coefficient
                            k2 = k1 * BiCubicKernel((double)m - dx);

                            ox2 = ox1 + m;
                            if (ox2 < 0)
                                ox2 = 0;
                            if (ox2 > xmax)
                                ox2 = xmax;

                            // Get pixel of original image
                            int srcPos = (ox2 * bitmap.FormatWidth) + (bitmap.Stride * oy2);
                            r += k2 * bitmap.Data[srcPos++];
                            g += k2 * bitmap.Data[srcPos++];
                            b += k2 * bitmap.Data[srcPos++];
                            a += k2 * bitmap.Data[srcPos];
                        }
                    }

                    // Set destination pixel
                    int dstPos = (x * newBitmap.FormatWidth) + (newBitmap.Stride * y);
                    newBitmap.Data[dstPos++] = (byte)r;
                    newBitmap.Data[dstPos++] = (byte)g;
                    newBitmap.Data[dstPos++] = (byte)b;
                    newBitmap.Data[dstPos] = (byte)a;
                }
            }

            return newBitmap;
        }
        protected override void Setup()
        {
            // Load native texture
            nativeTexture = DaggerfallUI.GetTextureFromImg(nativeImgName);
            if (!nativeTexture)
                throw new Exception("DaggerfallTravelMap: Could not load native texture.");

            // Always dim background
            ParentPanel.BackgroundColor = ScreenDimColor;

            // Setup native panel background
            NativePanel.BackgroundTexture = nativeTexture;

            // Populate the offset dict
            PopulateRegionOffsetDict();

            // Don't allow automatic cancel, we will handle this locally
            AllowCancel = false;

            // Load picker colours
            regionPickerBitmap = DaggerfallUI.GetImgBitmap(regionPickerImgName);

            // Add region label
            regionLabel = DaggerfallUI.AddTextLabel(DaggerfallUI.DefaultFont, new Vector2(0, 2), string.Empty, NativePanel);
            regionLabel.HorizontalAlignment = HorizontalAlignment.Center;

            // Handle clicks
            NativePanel.OnMouseClick += ClickHandler;

            // Setup buttons for first time
            LoadButtonTextures();
            SetupButtons();
            UpdateSearchButtons();

            // Region overlay panel
            regionTextureOverlayPanel = DaggerfallUI.AddPanel(regionTextureOverlayPanelRect, NativePanel);
            regionTextureOverlayPanel.Enabled = false;

            // Location cluster panel
            locationClusterPanel = DaggerfallUI.AddPanel(regionTextureOverlayPanelRect, regionTextureOverlayPanel);
            locationClusterPanel.HorizontalAlignment = HorizontalAlignment.Left;
            locationClusterPanel.VerticalAlignment = VerticalAlignment.Top;

            // Location cluster will be updated when user opens a region
            locationClusterColors = new Color32[(int)regionTextureOverlayPanelRect.width * (int)regionTextureOverlayPanelRect.height];
            locationClusterTexture = new Texture2D((int)regionTextureOverlayPanelRect.width, (int)regionTextureOverlayPanelRect.height);
            locationClusterTexture.filterMode = DaggerfallUI.Instance.GlobalFilterMode;

            // Overlay to identify player region
            identifyRegionOverlayTexture = CreatePlayerRegionOverlayTexture();

            // Identify region panel is displayed to show user what region they are in
            identifyRegionPanel = new Panel();
            identifyRegionPanel.Position = new Vector2(0, 0);
            identifyRegionPanel.Size = NativePanel.Size;
            identifyRegionPanel.BackgroundTexture = identifyRegionOverlayTexture;
            identifyRegionPanel.Enabled = false;
            NativePanel.Components.Add(identifyRegionPanel);
        }
 /// <summary>
 /// Fills DFBitmap with specified values.
 /// </summary>
 /// <param name="bitmap">DFBitmap to fill.</param>
 /// <param name="r">Red value.</param>
 /// <param name="g">Green value.</param>
 /// <param name="b">Blue value.</param>
 /// <param name="a">Alpha value.</param>
 public static void Fill(DFBitmap bitmap, byte r, byte g, byte b, byte a)
 {
     // Fill with value and alpha
     for (int pos = 0; pos < bitmap.Data.Length; pos += bitmap.FormatWidth)
     {
         bitmap.Data[pos] = r;
         bitmap.Data[pos + 1] = g;
         bitmap.Data[pos + 2] = b;
         bitmap.Data[pos + 3] = a;
     }
 }
 /// <summary>
 /// Fills DFBitmap with specified colour.
 /// </summary>
 /// <param name="bitmap">DFBitmap to fill.</param>
 /// <param name="color">Source colour.</param>
 public static void Fill(DFBitmap bitmap, DFColor color)
 {
     Fill(bitmap, color.r, color.g, color.b, color.a);
 }
 /// <summary>
 /// Sets pixel in DFBitmap. Colour formats only.
 /// </summary>
 /// <param name="bitmap">DFBitmap.</param>
 /// <param name="x">X position.</param>
 /// <param name="y">Y position.</param>
 /// <param name="r">Red value.</param>
 /// <param name="g">Green value.</param>
 /// <param name="b">Blue value.</param>
 /// <param name="a">Alpha value.</param>
 public static void SetPixel(DFBitmap bitmap, int x, int y, byte r, byte g, byte b, byte a)
 {
     SetPixel(bitmap, x, y, DFColor.FromRGBA(r, g, b, a));
 }
        protected override void Setup()
        {
            // Load native texture
            nativeTexture = DaggerfallUI.GetTextureFromImg(nativeImgName);
            if (!nativeTexture)
                throw new Exception("CreateCharRaceSelect: Could not load native texture.");

            // Load picker colours
            racePickerBitmap = DaggerfallUI.GetImgBitmap(racePickerImgName);

            // Setup native panel background
            NativePanel.BackgroundTexture = nativeTexture;

            // Add "Please select your home province..." prompt
            promptLabel = DaggerfallUI.AddTextLabel(DaggerfallUI.DefaultFont, new Vector2(0, 16), HardStrings.pleaseSelectYourHomeProvince, NativePanel);
            promptLabel.HorizontalAlignment = HorizontalAlignment.Center;
            promptLabel.TextColor = DaggerfallUI.DaggerfallDefaultTextColor;
            promptLabel.ShadowColor = DaggerfallUI.DaggerfallDefaultShadowColor;
            promptLabel.ShadowPosition = DaggerfallUI.DaggerfallDefaultShadowPos;

            // Handle clicks
            NativePanel.OnMouseClick += ClickHandler;
        }
        /// <summary>
        /// Converts full colour DFBitmap to Color32 array.
        /// </summary>
        /// <param name="bitmap">Source DFBitmap.</param>
        /// <param name="flipY">Flip Y rows so bottom becomes top.</param>
        /// <returns>Color32 array.</returns>
        public static Color32[] ConvertToColor32(DFBitmap bitmap, bool flipY = true)
        {
            // Must be RGBA format
            if (bitmap.Format != DFBitmap.Formats.RGBA)
                return null;

            // Create destination array
            Color32[] colors = new Color32[bitmap.Width * bitmap.Height];

            int index = 0;
            for (int y = 0; y < bitmap.Height; y++)
            {
                int rowOffset = (flipY) ? (bitmap.Height - 1 - y) * bitmap.Stride : y * bitmap.Stride;
                for (int x = 0; x < bitmap.Width; x++)
                {
                    // Get color bytes
                    int pos = rowOffset + x * bitmap.FormatWidth;
                    byte r = bitmap.Data[pos++];
                    byte g = bitmap.Data[pos++];
                    byte b = bitmap.Data[pos++];
                    byte a = bitmap.Data[pos];

                    // Store in array
                    colors[index++] = new Color32(r, g, b, a);
                }
            }

            return colors;
        }
        /// <summary>
        /// Gets pixel DFColor from DFBitmap.
        /// </summary>
        /// <param name="bitmap">DFBitmap.</param>
        /// <param name="x">X position.</param>
        /// <param name="y">Y position.</param>
        /// <returns>DFColor.</returns>
        public static DFColor GetPixel(DFBitmap bitmap, int x, int y)
        {
            DFColor color = new DFColor();
            int srcPos = y * bitmap.Stride + x * bitmap.FormatWidth;
            color.r = bitmap.Data[srcPos++];
            color.g = bitmap.Data[srcPos++];
            color.b = bitmap.Data[srcPos++];
            color.a = bitmap.Data[srcPos++];

            return color;
        }
        /// <summary>
        /// Creates a grayscale version of bitmap based on colour theory.
        /// </summary>
        /// <param name="bitmap">Source DFBitmap.</param>
        /// <returns>Grayscale DFBitmap image.</returns>
        public static DFBitmap MakeGrayscale(DFBitmap bitmap)
        {
            // Must be a colour format
            if (bitmap.Format == DFBitmap.Formats.Indexed)
                return null;

            DFBitmap newBitmap = new DFBitmap();
            newBitmap.Format = bitmap.Format;
            newBitmap.Initialise(bitmap.Width, bitmap.Height);

            // Make each pixel grayscale
            int srcPos = 0, dstPos = 0;
            for (int i = 0; i < bitmap.Width * bitmap.Height; i++)
            {
                // Get source color
                byte r = bitmap.Data[srcPos++];
                byte g = bitmap.Data[srcPos++];
                byte b = bitmap.Data[srcPos++];
                byte a = bitmap.Data[srcPos++];

                // Create grayscale color
                int grayscale = (int)(r * 0.3f + g * 0.59f + b * 0.11f);
                DFBitmap.DFColor dstColor = DFBitmap.DFColor.FromRGBA((byte)grayscale, (byte)grayscale, (byte)grayscale, a);

                // Write destination pixel
                newBitmap.Data[dstPos++] = dstColor.r;
                newBitmap.Data[dstPos++] = dstColor.g;
                newBitmap.Data[dstPos++] = dstColor.b;
                newBitmap.Data[dstPos++] = dstColor.a;
            }

            return newBitmap;
        }
        // Creates the region overlay for current player region
        Texture2D CreatePlayerRegionOverlayTexture()
        {
            try
            {
                // Player must be inside a valid region
                int playerRegion = GetPlayerRegion();
                if (playerRegion == -1)
                    return null;

                if (regionPickerBitmap == null)
                    regionPickerBitmap = DaggerfallUI.GetImgBitmap(regionPickerImgName);

                // Create a texture map overlay for the region area
                int width = regionPickerBitmap.Width;
                int height = regionPickerBitmap.Height;

                Texture2D texture = new Texture2D(width, height);
                texture.filterMode = DaggerfallUI.Instance.GlobalFilterMode;

                // Create array for region fill
                Color32[] colors = new Color32[width * height];
                for (int y = 0; y < height; y++)
                {
                    for (int x = 0; x < width; x++)
                    {
                        int srcOffset = y * width + x;
                        int dstOffset = ((height - y - 1) * width) + x;
                        int sampleRegion = regionPickerBitmap.Data[srcOffset] - 128;
                        if (sampleRegion == playerRegion)
                            colors[dstOffset] = identifyFlashColor;
                    }
                }

                // Assign colors to texture
                texture.SetPixels32(colors, 0);
                texture.Apply();
                return texture;
            }
            catch(Exception ex)
            {
                Debug.LogError(string.Format("{0}\n{1}", ex.TargetSite, ex.Message));
                return null;
            }
        }