public ImageSetterManipulator() : base(new CodedImage { Size = new Size(1, 1) }) { SourceImage.Pixels[0] = ColorBytes.ToArgb(0, 255, 255, 255); SourceImage.CompletePalette(); }
internal static ColorBytes BlendNormal(ColorBytes src, ColorBytes dst, byte opacity) { if (dst.A == 0) { // Destination is invisible, only blend source src.A = MultiplyU8(src.A, opacity); return(src); } else if (src.A == 0) { // Source color is invisible, only provide destination. return(dst); } // src.A = MultiplyU8(src.A, opacity); // var Ra = (byte)(src.A + dst.A - MultiplyU8(dst.A, src.A)); var Rr = (byte)(dst.R + (src.R - dst.R) * src.A / Ra); var Rg = (byte)(dst.G + (src.G - dst.G) * src.A / Ra); var Rb = (byte)(dst.B + (src.B - dst.B) * src.A / Ra); return(new ColorBytes(Rr, Rg, Rb, Ra)); }
protected void PaintCharacterLeftToRight(CharacterBitmap characterBitmap, int[] imagePixels, Size imageSize, Point atPoint, Rectangle clipRect, int fontRgb = 0) { var imageX = atPoint.X + characterBitmap.OffsetX; var imageY = atPoint.Y + characterBitmap.OffsetY; var bitmapLeft = imageX < clipRect.Left ? clipRect.Left - imageX : 0; var bitmapTop = imageY < clipRect.Top ? clipRect.Top - imageY : 0; var localClipRect = new Rectangle( bitmapLeft, bitmapTop, Math.Min(clipRect.RightExclusive - imageX, characterBitmap.Width - bitmapLeft), Math.Min(clipRect.BottomExclusive - imageY, characterBitmap.Height - bitmapTop)); if (localClipRect.Height > 0 && localClipRect.Width > 0) { for (int y = localClipRect.Top, bitmapRow = localClipRect.Top * characterBitmap.Width, imageRow = (localClipRect.Top + imageY) * imageSize.Width; y < localClipRect.BottomExclusive; y++, bitmapRow += characterBitmap.Width, imageRow += imageSize.Width) { for (int x = localClipRect.Left, bitmapIndex = bitmapRow + localClipRect.Left, imageIndex = imageRow + localClipRect.Left + imageX; x < localClipRect.RightExclusive; x++, bitmapIndex++, imageIndex++) { imagePixels[imageIndex] = ColorBytes.ComposeTwoColors(imagePixels[imageIndex], fontRgb, characterBitmap.Bitmap[bitmapIndex]); } } } }
internal static ColorBytes BlendAddition(ColorBytes src, ColorBytes dst, byte opacity) { src.R = (byte)Calc.Min(dst.R + src.R, 0xFF); src.G = (byte)Calc.Min(dst.G + src.G, 0xFF); src.B = (byte)Calc.Min(dst.B + src.B, 0xFF); return(BlendNormal(src, dst, opacity)); }
internal static ColorBytes BlendSubtract(ColorBytes src, ColorBytes dst, byte opacity) { src.R = (byte)Calc.Max(dst.R - src.R, 0); src.G = (byte)Calc.Max(dst.G - src.G, 0); src.B = (byte)Calc.Max(dst.B - src.B, 0); return(BlendNormal(src, dst, opacity)); }
public void TestComposeTwoColors() { Assert.AreEqual(0x00000000, ColorBytes.ComposeTwoColors(0x003377ff, 0x00000000, 255)); Assert.AreEqual(0x003377ff, ColorBytes.ComposeTwoColors(0x00000000, 0x003377ff, 255)); Assert.AreEqual(0x003377ff, ColorBytes.ComposeTwoColors(0x003377ff, 0x00000000, 0)); Assert.AreEqual(0x00000000, ColorBytes.ComposeTwoColors(0x00000000, 0x003377ff, 0)); Assert.AreEqual(0x11662266, ColorBytes.ComposeTwoColors(0x11880088, 0x22008800, 63)); Assert.AreEqual(0x11662266, ColorBytes.ComposeTwoColors(0x11880088, 0x22008800, 64)); // Same due to rounding }
int GetShadeColor(int color) { const int coeff = 32; var r = AdjustComponent(color.Red(), coeff); var g = AdjustComponent(color.Green(), coeff); var b = AdjustComponent(color.Blue(), coeff); return(ColorBytes.ToArgb(color.Alpha(), r, g, b)); }
public static void ShadeImage(IndexedImage image, int argb, IndexedImage maskImage = null) { Debug.Assert(maskImage == null || maskImage.Size.Equals(image.Size), "maskImage should have same size as image"); for (int i = 0; i < image.Pixels.Length; i++) { var shadeArgb = maskImage != null?ColorBytes.ShadeColor(argb, maskImage.Pixels[i]) : argb; image.Pixels[i] = ColorBytes.ShadeColor(image.Pixels[i], shadeArgb); } }
public byte GetValue(ColorBytes color) { switch (color) { case ColorBytes.Red: return Convert.ToByte(RedSlider.CurrentValue); case ColorBytes.Blue: return Convert.ToByte(BlueSlider.CurrentValue); case ColorBytes.Green: return Convert.ToByte(GreenSlider.CurrentValue); } return 255; }
public byte GetValue(ColorBytes color) { switch (color) { case ColorBytes.Red: return(Convert.ToByte(RedSlider.CurrentValue)); case ColorBytes.Blue: return(Convert.ToByte(BlueSlider.CurrentValue)); case ColorBytes.Green: return(Convert.ToByte(GreenSlider.CurrentValue)); } return(255); }
/// <summary> /// Changes sizes of one pixel's line. /// </summary> /// <param name="oldArray">Old array with pixels.</param> /// <param name="newArray">New array with pixels.</param> /// <param name="oldStartIndex">Start index in old array.</param> /// <param name="newStartIndex">Start index in new array.</param> /// <param name="oldOneStep">Distance between points in old array.</param> /// <param name="newOneStep">Distance between points in new array.</param> private void ResampleLine(int[] oldArray, int[] newArray, int oldStartIndex, int newStartIndex, int oldOneStep, int newOneStep) { // By all pixels in new array // weightedValues.Length == new length for (int i = 0, newIndexPart = newStartIndex; i < weightedValues.Length; i++, newIndexPart += newOneStep) { // Initialize new color components 0.5 is for smoother truncating (instead of Math.Round) int b, g, r, a; b = g = r = a = 0; WeightedValue[] weightedValuesList = weightedValues[i]; for (int j = 0; j < weightedValuesList.Length; j++) { // Get index and weight of old element int weight = weightedValuesList[j].Weight; int oldIndex = oldStartIndex + weightedValuesList[j].Index * oldOneStep; if (oldIndex < 0) { oldIndex = 0; } if (oldIndex >= oldArray.Length) { oldIndex = oldArray.Length - 1; } // Update color components int argb = oldArray[oldIndex]; b += weight * argb.Blue(); g += weight * argb.Green(); r += weight * argb.Red(); a += weight * argb.Alpha(); } // Calculate index of pixel in new array int newIndex = newIndexPart; if (newIndex < 0) { newIndex = 0; } if (newIndex >= newArray.Length) { newIndex = oldArray.Length - 1; } // Save new color newArray[newIndex] = ColorBytes.ToArgb(GetNormalizedValue(a), GetNormalizedValue(r), GetNormalizedValue(g), GetNormalizedValue(b)); } }
void PaintCharacterRotated(CharacterBitmap characterBitmap, int[] imagePixels, Size imageSize, Point atPoint, Rectangle clipRect, TextDirection direction, int fontRgb) { int imageX, imageY, imageStepDX, imageStepDY, imageNextRowDX, imageNextRowDY; switch (direction) { case TextDirection.VerticalUpward: imageX = atPoint.X + characterBitmap.OffsetY; imageY = atPoint.Y - characterBitmap.OffsetX; imageStepDX = 0; imageStepDY = -1; imageNextRowDX = 1; imageNextRowDY = 0; break; case TextDirection.VerticalDownward: imageX = atPoint.X - characterBitmap.OffsetY; imageY = atPoint.Y + characterBitmap.OffsetX; imageStepDX = 0; imageStepDY = 1; imageNextRowDX = -1; imageNextRowDY = 0; break; case TextDirection.LeftToRight: default: PaintCharacterLeftToRight(characterBitmap, imagePixels, imageSize, atPoint, clipRect, fontRgb); return; } var imageIndexStep = imageStepDY * imageSize.Width + imageStepDX; for (int y = 0, bitmapRow = 0; y < characterBitmap.Height; y++, bitmapRow += characterBitmap.Width, imageX += imageNextRowDX, imageY += imageNextRowDY) { for (int x = 0, bitmapIndex = bitmapRow, iX = imageX, iY = imageY, imageIndex = imageY * imageSize.Width + imageX; x < characterBitmap.Width; x++, bitmapIndex++, iX += imageStepDX, iY += imageStepDY, imageIndex += imageIndexStep) { if (iX >= clipRect.Left && iX < clipRect.RightExclusive && iY >= clipRect.Top && iY < clipRect.BottomExclusive) { imagePixels[imageIndex] = ColorBytes.ComposeTwoColors(imagePixels[imageIndex], fontRgb, characterBitmap.Bitmap[bitmapIndex]); } } } }
private ColorBytes BlendColor(ColorBytes src, ColorBytes dst, byte opacity, BlendMode blend) { switch (blend) { default: return(src); case BlendMode.Normal: return(BlendNormal(src, dst, opacity)); case BlendMode.Addition: return(BlendAddition(src, dst, opacity)); case BlendMode.Subtract: return(BlendSubtract(src, dst, opacity)); } }
private void CopyDataToPixelArray(byte[] data, ColorBytes[] pixels) { if (pixels.Length * (_colorDepth / 8) != data.Length) { throw new InvalidOperationException("Pixel storage and data length don't match...?"); } if (_colorDepth == 32) { // RGBA for (var i = 0; i < pixels.Length; i++) { var R = data[i * 4 + 0]; var G = data[i * 4 + 1]; var B = data[i * 4 + 2]; var A = data[i * 4 + 3]; pixels[i] = new ColorBytes(R, G, B, A); } } else if (_colorDepth == 16) { // Grayscale + Alpha for (var i = 0; i < pixels.Length; i++) { var G = data[i * 2 + 0]; var A = data[i * 2 + 1]; pixels[i] = new ColorBytes(G, G, G, A); } } else { // Indexed for (var i = 0; i < pixels.Length; i++) { var color = Palette[data[i]]; pixels[i] = color; } } }
private ColorBytes[] ReadPaletteChunk() { var size = ReadDWord(); var palette = new ColorBytes[size]; var from = ReadDWord(); var to = ReadDWord(); ReadBytes(8); // spec, for future use DebugPrint($" Reading New Palette: {size} from {from} to {to}"); // For the colors in the range for (var i = from; i <= to; i++) { var flags = (PaletteEntryFlags)ReadWord(); var R = ReadByte(); var G = ReadByte(); var B = ReadByte(); var A = ReadByte(); // palette[i] = new ColorBytes(R, G, B, A); // if (flags.HasFlag(PaletteEntryFlags.HasName)) { var name = ReadString(); DebugPrint($" Color {i}: {palette[i]} ({name})"); } else { DebugPrint($" Color {i}: {palette[i]}"); } } // We have loaded the new palette, set a flag so we can ignore the old palette format _isNewPalette = true; return(palette); }
public VisualSymbolsController(ImageSymbolsController controller, Size imageBoxSize = default(Size)) : base(controller.Manipulator, imageBoxSize) { using (SuspendUpdateVisualImage()) { Controller = controller; CellSize = 32; HighlightedCell = new Point(-1, -1); PlainBackground = ColorBytes.ToArgb(0, 255, 255, 255); PlainFontColor = ColorBytes.ToArgb(0, 0, 0, 0); SelectedBackground = ColorBytes.ToArgb(0, 255, 127, 80); SelectedFontColor = PlainFontColor; HighlightedPlainBackground = ColorBytes.ToArgb(0, 0, 149, 237); HighlightedPlainFontColor = ColorBytes.ToArgb(0, 255, 255, 255); HighlightedSelectedBackground = ColorBytes.ToArgb(0, 0, 128, 255); HighlightedSelectedFontColor = HighlightedPlainFontColor; UpdateParametersAndVisualImage(); } }
static void ColorCursorImage(IndexedImage image, int argb) { int[] pixels; using (image.LockPixels(out pixels)) { Parallel.For(0, pixels.Length, index => { var pixelArgb = pixels[index]; var a = pixelArgb.Alpha(); if (a != 0) // Skip transparent { var r = pixelArgb.Red(); var g = pixelArgb.Green(); var b = pixelArgb.Blue(); if (Math.Abs(r - g) + Math.Abs(g - b) + Math.Abs(b - r) <= 12) // Close to grey colors { pixels[index] = ColorBytes.ShadeColor(pixelArgb, argb); } } }); } }
private ColorBytes[] ReadOldPaletteChunk(int depth) { var packetCount = ReadWord(); var palette = new ColorBytes[256]; // For each packet for (var p = 0; p < packetCount; p++) { var offset = ReadByte(); var count = ReadByte(); // For each color for (var c = 0; c < count; c++) { var r = (byte)(ReadByte() / (float)depth * 0xFF); var g = (byte)(ReadByte() / (float)depth * 0xFF); var b = (byte)(ReadByte() / (float)depth * 0xFF); palette[offset + c] = new ColorBytes(r, g, b); } } // Have new palette, return that instead. return(_isNewPalette && Palette != null ? Palette : palette); }
public void TestComponentsComposition() { Assert.AreEqual(0x12345678, ColorBytes.ToArgb(0x12, 0x34, 0x56, 0x78)); }