Browse Source

Fix transparency issues caused by rounding.

Former-commit-id: 54a03e11c23470c8f6f195c5b403eff2b7b6bf42
Former-commit-id: bed20d51eb17f0855cc1c122af34af1226f3b1f1
Former-commit-id: f04832c77a4b550059acfd716f766be278bf510a
pull/17/head
James Jackson-South 11 years ago
parent
commit
d8f19a095e
  1. 2
      src/ImageProcessor/Formats/Gif/GifEncoder.cs
  2. 14
      src/ImageProcessor/Formats/Gif/Quantizer/OctreeQuantizer.cs
  3. 50
      tests/ImageProcessor.Tests/Processors/Filters/FilterTests.cs

2
src/ImageProcessor/Formats/Gif/GifEncoder.cs

@ -57,7 +57,7 @@ namespace ImageProcessor.Formats
// Write the LSD and check to see if we need a global color table. // Write the LSD and check to see if we need a global color table.
// Always true just now. // Always true just now.
bool globalColor = this.WriteGlobalLogicalScreenDescriptor(image, stream, bitDepth); this.WriteGlobalLogicalScreenDescriptor(image, stream, bitDepth);
QuantizedImage quantized = this.WriteColorTable(imageBase, stream, quality, bitDepth); QuantizedImage quantized = this.WriteColorTable(imageBase, stream, quality, bitDepth);
this.WriteGraphicalControlExtension(imageBase, stream); this.WriteGraphicalControlExtension(imageBase, stream);

14
src/ImageProcessor/Formats/Gif/Quantizer/OctreeQuantizer.cs

@ -8,6 +8,8 @@ namespace ImageProcessor.Formats
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using ImageProcessor.Common.Extensions;
/// <summary> /// <summary>
/// Encapsulates methods to calculate the colour palette if an image using an Octree pattern. /// Encapsulates methods to calculate the colour palette if an image using an Octree pattern.
/// <see href="http://msdn.microsoft.com/en-us/library/aa479306.aspx"/> /// <see href="http://msdn.microsoft.com/en-us/library/aa479306.aspx"/>
@ -60,6 +62,11 @@ namespace ImageProcessor.Formats
this.maxColors = maxColors; this.maxColors = maxColors;
} }
/// <summary>
/// Gets or sets the transparency threshold.
/// </summary>
public byte Threshold { get; set; } = 128;
/// <summary> /// <summary>
/// Process the pixel in the first pass of the algorithm /// Process the pixel in the first pass of the algorithm
/// </summary> /// </summary>
@ -90,8 +97,8 @@ namespace ImageProcessor.Formats
// The color at [maxColors] is set to transparent // The color at [maxColors] is set to transparent
byte paletteIndex = (byte)this.maxColors; byte paletteIndex = (byte)this.maxColors;
// Get the palette index if this non-transparent // Get the palette index if it's transparency meets criterea.
if (pixel.A > 0) if (pixel.A >= this.Threshold)
{ {
paletteIndex = (byte)this.octree.GetPaletteIndex(pixel); paletteIndex = (byte)this.octree.GetPaletteIndex(pixel);
} }
@ -110,7 +117,6 @@ namespace ImageProcessor.Formats
// First off convert the Octree to maxColors colors // First off convert the Octree to maxColors colors
List<Bgra32> palette = this.octree.Palletize(Math.Max(this.maxColors - 1, 1)); List<Bgra32> palette = this.octree.Palletize(Math.Max(this.maxColors - 1, 1));
// Add empty color for transparency
palette.Add(Bgra32.Empty); palette.Add(Bgra32.Empty);
return palette; return palette;
@ -175,7 +181,7 @@ namespace ImageProcessor.Formats
/// <summary> /// <summary>
/// Gets or sets the number of leaves in the tree /// Gets or sets the number of leaves in the tree
/// </summary> /// </summary>
private int Leaves public int Leaves
{ {
get { return this.leafCount; } get { return this.leafCount; }
set { this.leafCount = value; } set { this.leafCount = value; }

50
tests/ImageProcessor.Tests/Processors/Filters/FilterTests.cs

@ -13,31 +13,31 @@ namespace ImageProcessor.Tests
{ {
public static readonly TheoryData<string, IImageProcessor> Filters = new TheoryData<string, IImageProcessor> public static readonly TheoryData<string, IImageProcessor> Filters = new TheoryData<string, IImageProcessor>
{ {
//{ "Brightness-50", new Brightness(50) }, { "Brightness-50", new Brightness(50) },
//{ "Brightness--50", new Brightness(-50) }, { "Brightness--50", new Brightness(-50) },
//{ "Contrast-50", new Contrast(50) }, { "Contrast-50", new Contrast(50) },
//{ "Contrast--50", new Contrast(-50) }, { "Contrast--50", new Contrast(-50) },
//{ "Blend", new Blend(new Image(File.OpenRead("../../TestImages/Formats/Bmp/Car.bmp")),15)}, { "Blend", new Blend(new Image(File.OpenRead("../../TestImages/Formats/Bmp/Car.bmp")),15)},
//{ "Saturation-50", new Saturation(50) }, { "Saturation-50", new Saturation(50) },
//{ "Saturation--50", new Saturation(-50) }, { "Saturation--50", new Saturation(-50) },
//{ "Alpha--50", new Alpha(50) }, { "Alpha--50", new Alpha(50) },
//{ "Invert", new Invert() }, { "Invert", new Invert() },
//{ "Sepia", new Sepia() }, { "Sepia", new Sepia() },
//{ "BlackWhite", new BlackWhite() }, { "BlackWhite", new BlackWhite() },
//{ "Lomograph", new Lomograph() }, { "Lomograph", new Lomograph() },
//{ "Polaroid", new Polaroid() }, { "Polaroid", new Polaroid() },
//{ "Kodachrome", new Kodachrome() }, { "Kodachrome", new Kodachrome() },
//{ "GreyscaleBt709", new GreyscaleBt709() }, { "GreyscaleBt709", new GreyscaleBt709() },
//{ "GreyscaleBt601", new GreyscaleBt601() }, { "GreyscaleBt601", new GreyscaleBt601() },
//{ "Kayyali", new Kayyali() }, { "Kayyali", new Kayyali() },
//{ "Kirsch", new Kirsch() }, { "Kirsch", new Kirsch() },
//{ "Laplacian3X3", new Laplacian3X3() }, { "Laplacian3X3", new Laplacian3X3() },
//{ "Laplacian5X5", new Laplacian5X5() }, { "Laplacian5X5", new Laplacian5X5() },
//{ "LaplacianOfGaussian", new LaplacianOfGaussian() }, { "LaplacianOfGaussian", new LaplacianOfGaussian() },
//{ "Prewitt", new Prewitt() }, { "Prewitt", new Prewitt() },
//{ "RobertsCross", new RobertsCross() }, { "RobertsCross", new RobertsCross() },
//{ "Scharr", new Scharr() }, { "Scharr", new Scharr() },
//{ "Sobel", new Sobel() }, { "Sobel", new Sobel() },
{ "GuassianBlur", new GuassianBlur(10) }, { "GuassianBlur", new GuassianBlur(10) },
{ "GuassianSharpen", new GuassianSharpen(10) } { "GuassianSharpen", new GuassianSharpen(10) }
}; };

Loading…
Cancel
Save