Arhn - архитектура программирования

Как мне сравнить два цвета в сценарии модульного тестирования?

Следующий тест не проходит.

[TestClass]//TestFixture
public class BitmapLockerUnitTest
{
    Bitmap bitmap = (Bitmap)Bitmap.FromFile(@"C:\lena.png");
    BitmapLocker locker;

    public BitmapLockerUnitTest()
    {
        locker = new BitmapLocker(bitmap);
    }

    [TestMethod]
    public void SetPixel__Test()
    {
        Bitmap copy = (Bitmap)bitmap.Clone();
        int xx = copy.Width / 2;
        int yy = copy.Height / 2;

        Color c = Color.Black;

        locker.Lock();
        locker.SetPixel(xx,yy,c);
        Assert.AreEqual(c, locker.GetPixel(xx,yy));
    }
}

Но должен ли я использовать здесь Color.Equal?

Если да, то как?

введите здесь описание изображения

Соответствующий исходный код

public class BitmapLocker : IDisposable
{
    //private properties
    Bitmap _bitmap = null;
    BitmapData _bitmapData = null;
    private byte[] _imageData = null;

    //public properties
    public bool IsLocked { get; set; }
    public IntPtr IntegerPointer { get; private set; }
    public int Width 
    { 
        get 
        {
            if (IsLocked == false) throw new InvalidOperationException("not locked");
            return _bitmapData.Width; 
        } 
    }
    public int Height 
    {
        get 
        {
            if (IsLocked == false) throw new InvalidOperationException("not locked");
            return _bitmapData.Height; 
        } 
    }
    public int Stride 
    { 
        get
        {
            if (IsLocked == false) throw new InvalidOperationException("not locked");
            return _bitmapData.Stride; 
        } 
    }
    public int ColorDepth 
    { 
        get 
        {
            if (IsLocked == false) throw new InvalidOperationException("not locked");
            return Bitmap.GetPixelFormatSize(_bitmapData.PixelFormat); 
        } 
    }
    public int Channels 
    { 
        get
        {
            if (IsLocked == false) throw new InvalidOperationException("not locked"); 
            return ColorDepth / 8; 
        } 
    }
    public int PaddingOffset 
    { 
        get 
        {
            if (IsLocked == false) throw new InvalidOperationException("not locked"); 
            return _bitmapData.Stride - (_bitmapData.Width * Channels); 
        } 
    }
    public PixelFormat ImagePixelFormat 
    { 
        get
        {
            if (IsLocked == false) throw new InvalidOperationException("not locked");
            return _bitmapData.PixelFormat; 
        } 
    }
    public bool IsGrayscale 
    { 
        get 
        {
            if (IsLocked == false) throw new InvalidOperationException("not locked");
            return Grayscale.IsGrayscale(_bitmap); 
        } 
    }

    //Constructor
    public BitmapLocker(Bitmap source)
    {
        IsLocked = false;
        IntegerPointer = IntPtr.Zero;
        this._bitmap = source;
    }

    /// Lock bitmap
    public void Lock()
    {
        if (IsLocked == false)
        {
            try
            {
                // Lock bitmap (so that no movement of data by .NET framework) and return bitmap data
                _bitmapData = _bitmap.LockBits(
                       new Rectangle(0, 0, _bitmap.Width, _bitmap.Height),
                       ImageLockMode.ReadWrite,
                       _bitmap.PixelFormat);

                // Create byte array to copy pixel values
                int noOfBytesNeededForStorage = Math.Abs(_bitmapData.Stride) * _bitmapData.Height;
                _imageData = new byte[noOfBytesNeededForStorage];

                IntegerPointer = _bitmapData.Scan0;

                // Copy data from IntegerPointer to _imageData
                Marshal.Copy(IntegerPointer, _imageData, 0, _imageData.Length);

                IsLocked = true;
            }
            catch (Exception)
            {
                throw;
            }
        }
        else
        {
            throw new Exception("Bitmap is already locked.");
        }
    }

    /// Unlock bitmap
    public void Unlock()
    {
        if (IsLocked == true)
        {
            try
            {
                // Copy data from _imageData to IntegerPointer
                Marshal.Copy(_imageData, 0, IntegerPointer, _imageData.Length);

                // Unlock bitmap data
                _bitmap.UnlockBits(_bitmapData);

                IsLocked = false;
            }
            catch (Exception)
            {
                throw;
            }
        }
        else
        {
            throw new Exception("Bitmap is not locked.");
        }
    }

    public Color GetPixel(int x, int y)
    {
        Color clr = Color.Empty;

        // Get color components count
        int cCount = ColorDepth / 8;

        // Get start index of the specified pixel
        int i = (Stride > 0 ? y : y - Height + 1) * Stride + x * cCount;

        int dataLength = _imageData.Length - cCount;

        if (i > dataLength)
        {
            throw new IndexOutOfRangeException();
        }

        if (ColorDepth == 32) // For 32 bpp get Red, Green, Blue and Alpha
        {
            byte b = _imageData[i];
            byte g = _imageData[i + 1];
            byte r = _imageData[i + 2];
            byte a = _imageData[i + 3]; // a
            clr = Color.FromArgb(a, r, g, b);
        }
        if (ColorDepth == 24) // For 24 bpp get Red, Green and Blue
        {
            byte b = _imageData[i];
            byte g = _imageData[i + 1];
            byte r = _imageData[i + 2];
            clr = Color.FromArgb(r, g, b);
        }
        if (ColorDepth == 8)
        // For 8 bpp get color value (Red, Green and Blue values are the same)
        {
            byte c = _imageData[i];
            clr = Color.FromArgb(c, c, c);
        }
        return clr;
    }

    public void SetPixel(int x, int y, Color color)
    {

        if (!IsLocked) throw new Exception();

        // Get color components count
        int cCount = ColorDepth / 8;

        // Get start index of the specified pixel
        int i = (Stride > 0 ? y : y - Height + 1) * Stride + x * cCount;

        try
        {
            if (ColorDepth == 32) // For 32 bpp set Red, Green, Blue and Alpha
            {
                _imageData[i] = color.B;
                _imageData[i + 1] = color.G;
                _imageData[i + 2] = color.R;
                _imageData[i + 3] = color.A;
            }
            if (ColorDepth == 24) // For 24 bpp set Red, Green and Blue
            {
                _imageData[i] = color.B;
                _imageData[i + 1] = color.G;
                _imageData[i + 2] = color.R;
            }
            if (ColorDepth == 8)
            // For 8 bpp set color value (Red, Green and Blue values are the same)
            {
                _imageData[i] = color.B;
            }
        }
        catch (Exception ex)
        {
            throw new Exception("(" + x + ", " + y + "), " + _imageData.Length + ", " + ex.Message + ", i=" + i);
        }
    }

    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }

    protected virtual void Dispose(bool disposing)
    {
        if (disposing)
        {
            // free managed resources
            _bitmap = null;
            _bitmapData = null;
            _imageData = null;
            IntegerPointer = IntPtr.Zero;
        }
    }
}

  • Попробуйте заменить Color c = Color.Black на «Color c = Color.FromArgb(255, 0, 0, 0)». 14.04.2017
  • @ Dennisvdh, да. но почему Color.Black не работает? 14.04.2017
  • Я не уверен, но если вы используете .ToArgb() или .ToKnownColor() с обеих сторон, сравнение должно работать правильно. И если я могу предложить, используйте первый. 14.04.2017
  • @Dennisvdh, брат, это именно то, что мне нужно знать. 14.04.2017
  • Согласен с @Dennisvdh - я имею в виду, что даже этот тест не проходит: [TestMethod] public void TestBlack() { Color c = Color.Black; Цвет c2 = Color.FromArgb(255, 0, 0, 0); Assert.AreEqual(c, c2); } 14.04.2017
  • Он задокументирован msdn.microsoft.com/en- us/library/e03x8ct2(v=vs.110).aspx 14.04.2017
  • @SirRufo, да. Но мне нужно правильно оформить тестовый пример. 14.04.2017
  • Затем перейдите и реализуйте IEqualityComparer‹Color›, который будет сравнивать только значения ARGB и использовать их в вызове Assert. 14.04.2017
  • Мне нужно правильно оформить тестовый пример — что именно? Если вы спрашиваете, как изменить тестируемый код, чтобы ваш модульный тест прошел без каких-либо изменений в нем, вы не можете. Это просто невозможно. Вы должны использовать FromArgb(), чтобы получить цвет сравнения, или Color.Black.ToArgb(), чтобы сравнить с пикселем, или любой другой механизм, который будет сравнивать только значения компонентов цвета вместо других свойств, которые включены в обычное сравнение Color. 14.04.2017
  • И редактирование ничего не изменило. Assert.AreEqual в настоящее время использует метод Color.Equals для проверки равенства, и это является причиной сбоя. 14.04.2017

Новые материалы

Коллекции публикаций по глубокому обучению
Последние пару месяцев я создавал коллекции последних академических публикаций по различным подполям глубокого обучения в моем блоге https://amundtveit.com - эта публикация дает обзор 25..

Представляем: Pepita
Фреймворк JavaScript с открытым исходным кодом Я знаю, что недостатка в фреймворках JavaScript нет. Но я просто не мог остановиться. Я хотел написать что-то сам, со своими собственными..

Советы по коду Laravel #2
1-) Найти // You can specify the columns you need // in when you use the find method on a model User::find(‘id’, [‘email’,’name’]); // You can increment or decrement // a field in..

Работа с временными рядами спутниковых изображений, часть 3 (аналитика данных)
Анализ временных рядов спутниковых изображений для данных наблюдений за большой Землей (arXiv) Автор: Рольф Симоэс , Жильберто Камара , Жильберто Кейрос , Фелипе Соуза , Педро Р. Андраде ,..

3 способа решить квадратное уравнение (3-й мой любимый) -
1. Методом факторизации — 2. Используя квадратичную формулу — 3. Заполнив квадрат — Давайте поймем это, решив это простое уравнение: Мы пытаемся сделать LHS,..

Создание VR-миров с A-Frame
Виртуальная реальность (и дополненная реальность) стали главными модными терминами в образовательных технологиях. С недорогими VR-гарнитурами, такими как Google Cardboard , и использованием..

Демистификация рекурсии
КОДЕКС Демистификация рекурсии Упрощенная концепция ошеломляющей О чем весь этот шум? Рекурсия, кажется, единственная тема, от которой у каждого начинающего студента-информатика..