private string BuildMobImageSmall(ViewableMonster mob) { var iconColumnValue = mob.Icon; var iconName = iconColumnValue.Substring(0, 4); if (listMonsters.SmallImageList.Images.ContainsKey(iconName) == false) { // [M014]010 var iconFilename = string.Format("{0}.dds", iconName); var iconFilepath = Path.Combine(MobIconDir, iconFilename); if (File.Exists(iconFilepath)) { var dds = new DdsFile(); using (var stream = File.OpenRead(iconFilepath)) { dds.Deserialize(stream); } var png = dds.AsPng(); listMonsters.SmallImageList.Images.Add(iconName, png); listMonsters.LargeImageList.Images.Add(iconName, png); } } return iconName; }
/// <summary> /// Apply <see cref="HSVShift"/> values to this DDS image based on the /// channels in the <paramref name="mask"/>. /// </summary> /// <param name="mask">A DDS image file, each colourway acting as a mask channel.</param> /// <param name="ch1Shift">A shift to apply to the image when the first channel of the mask is active.</param> /// <param name="ch2Shift">A shift to apply to the image when the second channel of the mask is active.</param> /// <param name="ch3Shift">A shift to apply to the image when the third channel of the mask is active.</param> /// <param name="ch4Shift">A shift to apply to the image when the fourth channel of the mask is active.</param> public void MaskedHSVShift(DdsFile mask, HSVShift ch1Shift, HSVShift ch2Shift, HSVShift ch3Shift, HSVShift ch4Shift) { if (!SupportsHSV) return; maskInEffect = maskInEffect || !ch1Shift.IsEmpty || !ch2Shift.IsEmpty || !ch3Shift.IsEmpty || !ch4Shift.IsEmpty; if (!maskInEffect) return; if (!ch1Shift.IsEmpty) MaskedHSVShift(mask, hsvData, x => x.R() > 0, ch1Shift); if (!ch2Shift.IsEmpty) MaskedHSVShift(mask, hsvData, x => x.G() > 0, ch2Shift); if (!ch3Shift.IsEmpty) MaskedHSVShift(mask, hsvData, x => x.B() > 0, ch3Shift); if (!ch4Shift.IsEmpty) MaskedHSVShift(mask, hsvData, x => x.A() > 0, ch4Shift); currentImage = ColorHSVA.ToArrayARGB(hsvData); }
void MaskedApplyImage(DdsFile mask, Channel channel, uint[] image, Size imageSize) { MaskedApply(this.currentImage, this.Size, mask.currentImage, mask.Size, channel, (x, y) => image[((y % imageSize.Height) * imageSize.Width) + (x % imageSize.Width)]); }
/// <summary> /// Creates an image from a given <see cref="T:DdsFile"/>. /// If <paramref name="supportHSV"/> is true, also creates an HSVa-encoded version of the image. /// </summary> /// <param name="image"><see cref="T:DdsFile"/> to clone.</param> /// <param name="supportHSV">When true, create an HSVa-encoded version of the image.</param> public void CreateImage(DdsFile image, bool supportHSV) { width = image.width; height = image.height; useBlockCompression = image.useBlockCompression; useLuminence = image.useLuminence; alphaDepth = image.alphaDepth; baseImage = (uint[])image.currentImage.Clone(); currentImage = (uint[])baseImage.Clone(); if (supportHSV) UpdateHSVData(); }
/// <summary> /// Creates a mask with given <paramref name="maskChannels"/> active and of given <paramref name="width"/> and <paramref name="height"/>. /// </summary> /// <param name="maskChannels">Which channels in the mask should be activated.</param> /// <param name="width">Width of image.</param> /// <param name="height">Height of image.</param> public void CreateMask(MaskChannel maskChannels, int width, int height) { ClearMask(); ddsMask = new DdsFile(); ddsMask.CreateImage( MaskChannelToByte(maskChannels, MaskChannel.C1), MaskChannelToByte(maskChannels, MaskChannel.C2), MaskChannelToByte(maskChannels, MaskChannel.C3), MaskChannelToByte(maskChannels, MaskChannel.C4), width, height, false); }
/// <summary> /// Load a mask to use for HSV shifting or masked application of colours. /// Clears any mask currently applied. /// </summary> /// <param name="mask"></param> public void LoadMask(Stream mask) { ClearMask(); try { base.Enabled = false; Application.UseWaitCursor = true; Application.DoEvents(); this.ddsMask = new DdsFile(); this.ddsMask.Load(mask, false);//only want the pixmap data } finally { base.Enabled = true; Application.UseWaitCursor = false; Application.DoEvents(); } }
/// <summary> /// Get a copy of the current DDS image as a <see cref="DdsFile"/>. /// </summary> /// <returns>A new <see cref="DdsFile"/> copy of the current DDS image.</returns> public DdsFile GetDdsFile() { if (!this.loaded || ddsFile == null) return null; DdsFile res = new DdsFile(); res.CreateImage(ddsFile, false); return res; }
/// <summary> /// Sets the DDS image for this <see cref="DDSPanel"/> from the given <paramref name="ddsfile"/>. /// <see cref="SupportsHSV"/> is determined from the <see cref="DdsFile.SupportsHSV"/> value. /// </summary> /// <param name="ddsfile">A <see cref="DdsFile"/> to display in this <see cref="DDSPanel"/>.</param> public void DDSLoad(DdsFile ddsfile) { this.ddsFile = ddsfile; loaded = true; this.supportHSV = ddsfile.SupportsHSV; ckb_CheckedChanged(null, null); }
/// <summary> /// Set the colour of the image based on the channels in the <paramref name="mask"/>. /// </summary> /// <param name="mask">The <see cref="System.IO.Stream"/> containing the DDS image to use as a mask.</param> /// <param name="ch1Colour">(Nullable) ARGB colour to the image when the first channel of the mask is active.</param> /// <param name="ch2Colour">(Nullable) ARGB colour to the image when the second channel of the mask is active.</param> /// <param name="ch3Colour">(Nullable) ARGB colour to the image when the third channel of the mask is active.</param> /// <param name="ch4Colour">(Nullable) ARGB colour to the image when the fourth channel of the mask is active.</param> public void MaskedSetColour(DdsFile mask, uint? ch1Colour, uint? ch2Colour, uint? ch3Colour, uint? ch4Colour) { maskInEffect = maskInEffect || ch1Colour.HasValue || ch2Colour.HasValue || ch3Colour.HasValue || ch4Colour.HasValue; if (!maskInEffect) return; if (ch1Colour.HasValue) MaskedSetColour(mask, x => x.R() > 0, ch1Colour.Value); if (ch2Colour.HasValue) MaskedSetColour(mask, x => x.G() > 0, ch2Colour.Value); if (ch3Colour.HasValue) MaskedSetColour(mask, x => x.B() > 0, ch3Colour.Value); if (ch4Colour.HasValue) MaskedSetColour(mask, x => x.A() > 0, ch4Colour.Value); if (SupportsHSV) UpdateHSVData(); }
/// <summary> /// Converts the R, G and B channels of the supplied <paramref name="image"/> to greyscale /// and loads this into the Alpha channel of the current image. /// The image format will be changed to one supporting an 8-bit Alpha channel, if required. /// </summary> /// <param name="image"><see cref="DdsFile"/> to extract greyscale data from for alpha channel.</param> public void SetAlphaFromGreyscale(DdsFile image) { AlphaDepth = UseDXT ? 5 : 8; SetPixels((x, y, value) => { uint alpha; lock (image) { uint srcValue = image.GetPixel(x % image.width, y % image.height); alpha = ((srcValue.R() + srcValue.G() + srcValue.B()) / 3) & 0xff; } return (value & 0x00FFFFFF) | (alpha << 24); }); if (SupportsHSV) UpdateHSVData(); }
/// <summary> /// Get a new DdsFile of the given size based on the current image. /// </summary> /// <param name="size">The new size.</param> /// <returns>A new DdsFile of the given size based on the current image.</returns> public DdsFile Resize(Size size) { DdsFile ddsFile = new DdsFile(); ddsFile.CreateImage(this, size.Width, size.Height, SupportsHSV); return ddsFile; }
/// <summary> /// Creates an image from a given <see cref="T:Bitmap"/>, resized as requested. /// If <paramref name="supportHSV"/> is true, also creates an HSVa-encoded version of the image. /// </summary> /// <param name="image"><see cref="T:Bitmap"/> from which to extract image pixels.</param> /// <param name="width">Width of image.</param> /// <param name="height">Height of image.</param> /// <param name="supportHSV">When true, create an HSVa-encoded version of the image.</param> public void CreateImage(Bitmap image, int width, int height, bool supportHSV) { using (DdsFile ddsFileBase = new DdsFile()) { ddsFileBase.CreateImage(image, false); CreateImage(ddsFileBase.Resize(new Size(width, height)), supportHSV); } }
/// <summary> /// Creates an image from a given <see cref="T:DdsFile"/>, resized as requested. /// If <paramref name="supportHSV"/> is true, also creates an HSVa-encoded version of the image. /// </summary> /// <param name="image"><see cref="T:DdsFile"/> to clone.</param> /// <param name="width">Width of image.</param> /// <param name="height">Height of image.</param> /// <param name="supportHSV">When true, create an HSVa-encoded version of the image.</param> public void CreateImage(DdsFile image, int width, int height, bool supportHSV) { this.width = width; this.height = height; this.useBlockCompression = image.useBlockCompression; this.useLuminence = image.useLuminence; this.alphaDepth = image.alphaDepth; if (this.useLuminence) { // Life would be still relatively simple were it not for Luminence maps. // With these, you can't just strip the alpha channel -- they exist only for that channel, // so we need to deal with them separately. this.currentImage = new uint[width * height]; this.SetPixels((x, y, unused) => 0); this.baseImage = (uint[])this.currentImage.Clone(); Bitmap alpha = new Bitmap(image.GetGreyscaleFromAlpha(), width, height); this.SetAlphaFromGreyscale(alpha); } else if (alphaDepth == 0) { this.baseImage = new Bitmap(image.Image, width, height).ToARGBData(); this.currentImage = (uint[])this.baseImage.Clone(); } else { // Regardless of the pixel format, using Bitmap to resize the image pre-multiplies the alpha // so we need this mess. // Clone the image, strip the alpha, then resize using (DdsFile ddsFileBase = new DdsFile()) { ddsFileBase.CreateImage(image, false); ddsFileBase.DeleteAlphaChannel(); this.baseImage = new Bitmap(ddsFileBase.Image, width, height).ToARGBData(); } this.currentImage = (uint[])this.baseImage.Clone(); // Now reapply the original alpha Bitmap alpha = new Bitmap(image.GetGreyscaleFromAlpha(), width, height); this.SetAlphaFromGreyscale(alpha); } if (supportHSV) this.UpdateHSVData(); }
/// <summary> /// Creates an image from a given <see cref="T:DdsFile"/>. /// If <paramref name="supportHSV"/> is true, also creates an HSVa-encoded version of the image. /// </summary> /// <param name="image"><see cref="T:DdsFile"/> to clone.</param> /// <param name="supportHSV">When true, create an HSVa-encoded version of the image.</param> public void CreateImage(DdsFile image, bool supportHSV) { this.width = image.width; this.height = image.height; this.useBlockCompression = image.useBlockCompression; this.useLuminence = image.useLuminence; this.alphaDepth = image.alphaDepth; this.baseImage = (uint[])image.currentImage.Clone(); this.currentImage = (uint[])this.baseImage.Clone(); if (supportHSV) this.UpdateHSVData(); }
private void btnOpenMask_Click(object sender, EventArgs e) { openFileDialog1.FileName = "*.dds"; openFileDialog1.FilterIndex = 0; string caption = openFileDialog1.Title; try { openFileDialog1.Title = "Select DDS Image to use as a mask"; DialogResult dr = openFileDialog1.ShowDialog(); if (dr != DialogResult.OK) return; } finally { openFileDialog1.Title = caption; } using (FileStream fs = new FileStream(openFileDialog1.FileName, FileMode.Open, FileAccess.Read)) { using (DdsFile ddsfile = new DdsFile()) { ddsfile.Load(fs, false); fs.Position = 0; DdsFile ddsfile2 = ddsfile.Resize(ddsMaskCh1.Size); ddsMaskCh1.DDSLoad(ddsfile2); ddsMaskCh2.DDSLoad(ddsfile2); ddsMaskCh3.DDSLoad(ddsfile2); ddsMaskCh4.DDSLoad(ddsfile2); } ddsPanel1.LoadMask(fs); lbMaskW.Text = ddsPanel1.MaskSize.Width + ""; lbMaskH.Text = ddsPanel1.MaskSize.Height + ""; tlpMaskSize.Visible = true; fs.Close(); } }
/// <summary> /// Apply <see cref="HSVShift"/> values to this DDS image based on the /// channels in the <paramref name="mask"/>. /// Each channel of the mask acts independently, in order "R", "G", "B", "A". /// </summary> /// <param name="mask">A DDS image file, each colourway acting as a mask channel.</param> /// <param name="ch1Shift">A shift to apply to the image when the first channel of the mask is active.</param> /// <param name="ch2Shift">A shift to apply to the image when the second channel of the mask is active.</param> /// <param name="ch3Shift">A shift to apply to the image when the third channel of the mask is active.</param> /// <param name="ch4Shift">A shift to apply to the image when the fourth channel of the mask is active.</param> public void MaskedHSVShiftNoBlend(DdsFile mask, HSVShift ch1Shift, HSVShift ch2Shift, HSVShift ch3Shift, HSVShift ch4Shift) { if (!SupportsHSV) return; maskInEffect = maskInEffect || !ch1Shift.IsEmpty || !ch2Shift.IsEmpty || !ch3Shift.IsEmpty || !ch4Shift.IsEmpty; if (!maskInEffect) return; ColorHSVA[] result = new ColorHSVA[hsvData.Length]; Array.Copy(hsvData, 0, result, 0, result.Length); if (!ch1Shift.IsEmpty) MaskedHSVShift(mask, result, x => x.R() > 0, ch1Shift); if (!ch2Shift.IsEmpty) MaskedHSVShift(mask, result, x => x.G() > 0, ch2Shift); if (!ch3Shift.IsEmpty) MaskedHSVShift(mask, result, x => x.B() > 0, ch3Shift); if (!ch4Shift.IsEmpty) MaskedHSVShift(mask, result, x => x.A() > 0, ch4Shift); hsvData = result; currentImage = ColorHSVA.ToArrayARGB(hsvData); }
void MaskedHSVShift(DdsFile mask, ColorHSVA[] result, Channel channel, HSVShift hsvShift) { for (int y = 0; y < this.Size.Height; y++) { int imageOffset = y * this.Size.Width; int maskOffset = (y % mask.Size.Height) * mask.Size.Width; for (int x = 0; x < this.Size.Width; x++) { uint maskPixel = mask.currentImage[maskOffset + x % mask.Size.Width]; if (channel(maskPixel)) result[imageOffset + x] = hsvData[imageOffset + x].HSVShift(hsvShift); } } }
void MaskedSetColour(DdsFile mask, Channel channel, uint argb) { MaskedApply(this.currentImage, this.Size, mask.currentImage, mask.Size, channel, (x, y) => argb); }
/// <summary> /// Sets the DDSPanel to an unloaded state, freeing resources. /// </summary> public void Clear() { ddsFile = new DdsFile(); loaded = false; ddsMask = null; pictureBox1.Image = image = null; pictureBox1.Size = (this.MaxSize == Size.Empty) ? new Size(0x80, 0x80) : Min(new Size(0x80, 0x80), this.MaxSize); ckb_CheckedChanged(null, null); }
/// <summary> /// Use the <paramref name="mask"/> to apply the DDS image supplied. /// </summary> /// <param name="mask">Determines to which areas each DDS image is applied.</param> /// <param name="ch1DdsFile">DDS image applied to <paramref name="mask"/> channel 1 area.</param> /// <param name="ch2DdsFile">DDS image applied to <paramref name="mask"/> channel 2 area.</param> /// <param name="ch3DdsFile">DDS image applied to <paramref name="mask"/> channel 3 area.</param> /// <param name="ch4DdsFile">DDS image applied to <paramref name="mask"/> channel 4 area.</param> public void MaskedApplyImage(DdsFile mask, DdsFile ch1DdsFile, DdsFile ch2DdsFile, DdsFile ch3DdsFile, DdsFile ch4DdsFile) { this.MaskedApplyImage(mask, (ch1DdsFile == null) ? null : ch1DdsFile.currentImage, (ch1DdsFile == null) ? Size.Empty : ch1DdsFile.Size, (ch2DdsFile == null) ? null : ch2DdsFile.currentImage, (ch2DdsFile == null) ? Size.Empty : ch2DdsFile.Size, (ch3DdsFile == null) ? null : ch3DdsFile.currentImage, (ch3DdsFile == null) ? Size.Empty : ch3DdsFile.Size, (ch4DdsFile == null) ? null : ch4DdsFile.currentImage, (ch4DdsFile == null) ? Size.Empty : ch4DdsFile.Size); }
/// <summary> /// Set the alpha channel of the current image from the given DDS file stream. /// </summary> /// <param name="image"><see cref="Stream"/> containing a DDS image.</param> public void SetAlphaFromGreyscale(Stream image) { DdsFile greyscale = new DdsFile(); greyscale.Load(image, false); ddsFile.SetAlphaFromGreyscale(greyscale); ckb_CheckedChanged(null, null); }
/// <summary> /// Use the <paramref name="mask"/> to apply the supplied images. /// </summary> /// <param name="mask">Determines to which areas each image is applied.</param> /// <param name="ch1Image">Image applied to <paramref name="mask"/> channel 1 area.</param> /// <param name="ch2Image">Image applied to <paramref name="mask"/> channel 2 area.</param> /// <param name="ch3Image">Image applied to <paramref name="mask"/> channel 3 area.</param> /// <param name="ch4Image">Image applied to <paramref name="mask"/> channel 4 area.</param> public void MaskedApplyImage(DdsFile mask, Image ch1Image, Image ch2Image, Image ch3Image, Image ch4Image) { this.MaskedApplyImage(mask, (ch1Image == null) ? null : new Bitmap(ch1Image), (ch2Image == null) ? null : new Bitmap(ch2Image), (ch3Image == null) ? null : new Bitmap(ch3Image), (ch4Image == null) ? null : new Bitmap(ch4Image)); }
/// <summary> /// Removes any previously applied masked shifts /// </summary> public void ClearMask() { if (SupportsHSV) ddsFile.ClearMask(); ddsMask = null; if (loaded) ckb_CheckedChanged(null, null); }
/// <summary> /// Use the <paramref name="mask"/> to apply the supplied bitmaps. /// </summary> /// <param name="mask">Determines to which areas each image is applied.</param> /// <param name="ch1Bitmap">Bitmap applied to <paramref name="mask"/> channel 1 area.</param> /// <param name="ch2Bitmap">Bitmap applied to <paramref name="mask"/> channel 2 area.</param> /// <param name="ch3Bitmap">Bitmap applied to <paramref name="mask"/> channel 3 area.</param> /// <param name="ch4Bitmap">Bitmap applied to <paramref name="mask"/> channel 4 area.</param> public void MaskedApplyImage(DdsFile mask, Bitmap ch1Bitmap, Bitmap ch2Bitmap, Bitmap ch3Bitmap, Bitmap ch4Bitmap) { this.MaskedApplyImage(mask, (ch1Bitmap == null) ? null : ch1Bitmap.ToARGBData(), (ch1Bitmap == null) ? Size.Empty : ch1Bitmap.Size, (ch2Bitmap == null) ? null : ch2Bitmap.ToARGBData(), (ch2Bitmap == null) ? Size.Empty : ch2Bitmap.Size, (ch3Bitmap == null) ? null : ch3Bitmap.ToARGBData(), (ch3Bitmap == null) ? Size.Empty : ch3Bitmap.Size, (ch4Bitmap == null) ? null : ch4Bitmap.ToARGBData(), (ch4Bitmap == null) ? Size.Empty : ch4Bitmap.Size); }
/// <summary> /// Apply the supplied images to the areas of the base image defined by the /// channels in the currently loaded mask. /// </summary> /// <param name="ch1Image">The <see cref="T:System.IO.Stream"/> containing the DDS image to apply to the image when the first channel of the mask is active.</param> /// <param name="ch2Image">The <see cref="T:System.IO.Stream"/> containing the DDS image to apply to the image when the second channel of the mask is active.</param> /// <param name="ch3Image">The <see cref="T:System.IO.Stream"/> containing the DDS image to apply to the image when the third channel of the mask is active.</param> /// <param name="ch4Image">The <see cref="T:System.IO.Stream"/> containing the DDS image to apply to the image when the fourth channel of the mask is active.</param> public void ApplyImage(Stream ch1Image, Stream ch2Image, Stream ch3Image, Stream ch4Image) { if (!this.loaded || !this.MaskLoaded) return; DdsFile ch1dds = null, ch2dds = null, ch3dds = null, ch4dds = null; try { this.Enabled = false; Application.UseWaitCursor = true; Application.DoEvents(); if (ch1Image != null) { ch1dds = new DdsFile(); ch1dds.Load(ch1Image, false); } if (ch2Image != null) { ch2dds = new DdsFile(); ch2dds.Load(ch2Image, false); } if (ch3Image != null) { ch3dds = new DdsFile(); ch3dds.Load(ch3Image, false); } if (ch4Image != null) { ch4dds = new DdsFile(); ch4dds.Load(ch4Image, false); } ddsFile.MaskedApplyImage(this.ddsMask, ch1dds, ch2dds, ch3dds, ch4dds); } finally { this.Enabled = true; Application.UseWaitCursor = false; Application.DoEvents(); } this.ckb_CheckedChanged(null, null); }
void MaskedApplyImage(DdsFile mask, uint[] ch1image, Size ch1imageSize, uint[] ch2image, Size ch2imageSize, uint[] ch3image, Size ch3imageSize, uint[] ch4image, Size ch4imageSize) { maskInEffect = maskInEffect || ch1image != null || ch2image != null || ch3image != null || ch4image != null; if (!maskInEffect) return; if (ch1image != null) MaskedApplyImage(mask, x => x.R() > 0, ch1image, ch1imageSize); if (ch2image != null) MaskedApplyImage(mask, x => x.G() > 0, ch2image, ch2imageSize); if (ch3image != null) MaskedApplyImage(mask, x => x.B() > 0, ch3image, ch3imageSize); if (ch4image != null) MaskedApplyImage(mask, x => x.A() > 0, ch4image, ch4imageSize); if (SupportsHSV) UpdateHSVData(); }