public static void DoYBlur(ImageBuffer sourceDest) { if (sourceDest.BitDepth != 8) { throw new NotImplementedException("We only work with 8 bit at the moment."); } int height = sourceDest.Height; int width = sourceDest.Width; byte[] buffer = sourceDest.GetBuffer(); int strideInBytes = sourceDest.StrideInBytes(); byte[] cache = new byte[height]; for (int x = 0; x < width; x++) { int offset = x; for (int y = 0; y < height; y++) { cache[y] = buffer[offset]; offset += strideInBytes; } offset = x; for (int y = 1; y < height - 1; y++) { int newValue = (cache[y - 1] + cache[y] * 2 + cache[y + 1] + 2) / 4; // the + 2 is so that we will round correctly buffer[offset] = (byte)newValue; offset += strideInBytes; } } }
public static void DoErode3x3MinValue(ImageBuffer source, ImageBuffer dest) { if (source.BitDepth != 32 || dest.BitDepth != 32) { throw new NotImplementedException("We only work with 32 bit at the moment."); } if (source.Width != dest.Width || source.Height != dest.Height) { throw new NotImplementedException("Source and Dest have to be the same size"); } int height = source.Height; int width = source.Width; int sourceStrideInBytes = source.StrideInBytes(); int destStrideInBytes = dest.StrideInBytes(); byte[] sourceBuffer = source.GetBuffer(); byte[] destBuffer = dest.GetBuffer(); // This can be made much faster by holding the buffer pointer and offsets better // LBB 2013 06 09 for (int testY = 1; testY < height - 1; testY++) { for (int testX = 1; testX < width - 1; testX++) { RGBA_Bytes minColor = RGBA_Bytes.White; int sourceOffset = source.GetBufferOffsetXY(testX, testY - 1); // x-1, y-1 //minColor = MinColor(sourceBuffer, minColor, sourceOffset - 4); // x0, y-1 minColor = MinColor(sourceBuffer, minColor, sourceOffset + 0); // x1, y-1 //minColor = MinColor(sourceBuffer, minColor, sourceOffset + 4); // x-1, y0 minColor = MinColor(sourceBuffer, minColor, sourceOffset + sourceStrideInBytes - 4); // x0, y0 minColor = MinColor(sourceBuffer, minColor, sourceOffset + sourceStrideInBytes + 0); // x+1, y0 minColor = MinColor(sourceBuffer, minColor, sourceOffset + sourceStrideInBytes + 4); // x-1, y+1 //minColor = MinColor(sourceBuffer, minColor, sourceOffset + sourceStrideInBytes * 2 - 4); // x0, y+1 minColor = MinColor(sourceBuffer, minColor, sourceOffset + sourceStrideInBytes * 2 + 0); // x+1, y+1 //minColor = MinColor(sourceBuffer, minColor, sourceOffset + sourceStrideInBytes * 2 + 4); int destOffset = dest.GetBufferOffsetXY(testX, testY); destBuffer[destOffset + 2] = minColor.red; destBuffer[destOffset + 1] = minColor.green; destBuffer[destOffset + 0] = minColor.blue; destBuffer[destOffset + 3] = 255; } } }
public static void DoDilate3x3MaxValue(ImageBuffer source, ImageBuffer dest) { if (source.BitDepth != 32 || dest.BitDepth != 32) { throw new NotImplementedException("We only work with 32 bit at the moment."); } if (source.Width != dest.Width || source.Height != dest.Height) { throw new NotImplementedException("Source and Dest have to be the same size"); } int height = source.Height; int width = source.Width; int sourceStrideInBytes = source.StrideInBytes(); int destStrideInBytes = dest.StrideInBytes(); byte[] sourceBuffer = source.GetBuffer(); byte[] destBuffer = dest.GetBuffer(); for (int testY = 1; testY < height - 1; testY++) { for (int testX = 1; testX < width - 1; testX++) { RGBA_Bytes maxColor = RGBA_Bytes.Black; int sourceOffset = source.GetBufferOffsetXY(testX, testY -1); // x-1, y-1 //maxColor = MaxColor(sourceBuffer, maxColor, sourceOffset - 4); // x0, y-1 maxColor = MaxColor(sourceBuffer, maxColor, sourceOffset + 0); // x1, y-1 //maxColor = MaxColor(sourceBuffer, maxColor, sourceOffset + 4); // x-1, y0 maxColor = MaxColor(sourceBuffer, maxColor, sourceOffset + sourceStrideInBytes - 4); // x0, y0 maxColor = MaxColor(sourceBuffer, maxColor, sourceOffset + sourceStrideInBytes + 0); // x+1, y0 maxColor = MaxColor(sourceBuffer, maxColor, sourceOffset + sourceStrideInBytes + 4); // x-1, y+1 //maxColor = MaxColor(sourceBuffer, maxColor, sourceOffset + sourceStrideInBytes * 2 - 4); // x0, y+1 maxColor = MaxColor(sourceBuffer, maxColor, sourceOffset + sourceStrideInBytes * 2 + 0); // x+1, y+1 //maxColor = MaxColor(sourceBuffer, maxColor, sourceOffset + sourceStrideInBytes * 2 + 4); int destOffset = dest.GetBufferOffsetXY(testX, testY); destBuffer[destOffset + 2] = maxColor.red; destBuffer[destOffset + 1] = maxColor.green; destBuffer[destOffset + 0] = maxColor.blue; destBuffer[destOffset + 3] = 255; } } }
public ImageBuffer(ImageBuffer sourceImage) { SetDimmensionAndFormat(sourceImage.Width, sourceImage.Height, sourceImage.StrideInBytes(), sourceImage.BitDepth, sourceImage.GetBytesBetweenPixelsInclusive(), true); int offset = sourceImage.GetBufferOffsetXY(0, 0); byte[] buffer = sourceImage.GetBuffer(); byte[] newBuffer = new byte[buffer.Length]; agg_basics.memcpy(newBuffer, offset, buffer, offset, buffer.Length - offset); SetBuffer(newBuffer, offset); SetRecieveBlender(sourceImage.GetRecieveBlender()); }
public static void DoDilate3x3Binary(ImageBuffer source, ImageBuffer dest, int threshold) { if (source.BitDepth != 32 || dest.BitDepth != 32) { throw new NotImplementedException("We only work with 32 bit at the moment."); } if (source.Width != dest.Width || source.Height != dest.Height) { throw new NotImplementedException("Source and Dest have to be the same size"); } int height = source.Height; int width = source.Width; int sourceStrideInBytes = source.StrideInBytes(); int destStrideInBytes = dest.StrideInBytes(); byte[] sourceBuffer = source.GetBuffer(); byte[] destBuffer = dest.GetBuffer(); for (int testY = 1; testY < height-1; testY++) { for (int testX = 1; testX < width - 1; testX++) { for (int sourceY = -1; sourceY <= 1; sourceY++) { for (int sourceX = -1; sourceX <= 1; sourceX++) { int sourceOffset = source.GetBufferOffsetXY(testX + sourceX, testY + sourceY); if (sourceBuffer[sourceOffset] > threshold) { int destOffset = dest.GetBufferOffsetXY(testX, testY); destBuffer[destOffset++] = 255; destBuffer[destOffset++] = 255; destBuffer[destOffset++] = 255; destBuffer[destOffset++] = 255; } } } } } }
public bool Equals(ImageBuffer b, int maxError = 0) { if (Width == b.Width && Height == b.Height && BitDepth == b.BitDepth && StrideInBytes() == b.StrideInBytes() && m_OriginOffset == b.m_OriginOffset) { int bytesPerPixel = BitDepth / 8; int aDistanceBetweenPixels = GetBytesBetweenPixelsInclusive(); int bDistanceBetweenPixels = b.GetBytesBetweenPixelsInclusive(); byte[] aBuffer = GetBuffer(); byte[] bBuffer = b.GetBuffer(); for (int y = 0; y < Height; y++) { int aBufferOffset = GetBufferOffsetY(y); int bBufferOffset = b.GetBufferOffsetY(y); for (int x = 0; x < Width; x++) { for (int byteIndex = 0; byteIndex < bytesPerPixel; byteIndex++) { byte aByte = aBuffer[aBufferOffset + byteIndex]; byte bByte = bBuffer[bBufferOffset + byteIndex]; if (aByte < (bByte - maxError) || aByte > (bByte + maxError)) { return(false); } } aBufferOffset += aDistanceBetweenPixels; bBufferOffset += bDistanceBetweenPixels; } } return(true); } return(false); }
public bool Equals(ImageBuffer b, int maxError = 0) { if (Width == b.Width && Height == b.Height && BitDepth == b.BitDepth && StrideInBytes() == b.StrideInBytes() && m_OriginOffset == b.m_OriginOffset) { int bytesPerPixel = BitDepth / 8; int aDistanceBetweenPixels = GetBytesBetweenPixelsInclusive(); int bDistanceBetweenPixels = b.GetBytesBetweenPixelsInclusive(); byte[] aBuffer = GetBuffer(); byte[] bBuffer = b.GetBuffer(); for (int y = 0; y < Height; y++) { int aBufferOffset = GetBufferOffsetY(y); int bBufferOffset = b.GetBufferOffsetY(y); for (int x = 0; x < Width; x++) { for (int byteIndex = 0; byteIndex < bytesPerPixel; byteIndex++) { byte aByte = aBuffer[aBufferOffset + byteIndex]; byte bByte = bBuffer[bBufferOffset + byteIndex]; if (aByte < (bByte - maxError) || aByte > (bByte + maxError)) { return false; } } aBufferOffset += aDistanceBetweenPixels; bBufferOffset += bDistanceBetweenPixels; } } return true; } return false; }
public ImageBuffer(ImageBuffer sourceImage) { SetDimmensionAndFormat(sourceImage.Width, sourceImage.Height, sourceImage.StrideInBytes(), sourceImage.BitDepth, sourceImage.GetBytesBetweenPixelsInclusive(), true); int offset = sourceImage.GetBufferOffsetXY(0, 0); byte[] buffer = sourceImage.GetBuffer(); byte[] newBuffer = new byte[buffer.Length]; agg_basics.memcpy(newBuffer, offset, buffer, offset, buffer.Length - offset); SetBuffer(newBuffer, offset); SetRecieveBlender(sourceImage.GetRecieveBlender()); }
public static ImageBuffer GetCurrentScreen() { ImageBuffer screenCapture = new ImageBuffer(); Size sz = System.Windows.Forms.Screen.PrimaryScreen.Bounds.Size; IntPtr hDesk = GetDesktopWindow(); IntPtr hSrce = GetWindowDC(hDesk); IntPtr hDest = CreateCompatibleDC(hSrce); IntPtr hBmp = CreateCompatibleBitmap(hSrce, sz.Width, sz.Height); IntPtr hOldBmp = SelectObject(hDest, hBmp); bool b = BitBlt(hDest, 0, 0, sz.Width, sz.Height, hSrce, 0, 0, CopyPixelOperation.SourceCopy | CopyPixelOperation.CaptureBlt); Bitmap bmpScreenCapture = Bitmap.FromHbitmap(hBmp); SelectObject(hDest, hOldBmp); DeleteObject(hBmp); DeleteDC(hDest); ReleaseDC(hDesk, hSrce); //bmpScreenCapture.Save("bitmapsave.png"); screenCapture = new ImageBuffer(bmpScreenCapture.Width, bmpScreenCapture.Height, 32, new BlenderBGRA()); BitmapData bitmapData = bmpScreenCapture.LockBits(new Rectangle(0, 0, bmpScreenCapture.Width, bmpScreenCapture.Height), System.Drawing.Imaging.ImageLockMode.ReadWrite, bmpScreenCapture.PixelFormat); int offset; byte[] buffer = screenCapture.GetBuffer(out offset); int bitmapDataStride = bitmapData.Stride; int backBufferStrideInBytes = screenCapture.StrideInBytes(); int backBufferHeight = screenCapture.Height; int backBufferHeightMinusOne = backBufferHeight - 1; unsafe { byte* bitmapDataScan0 = (byte*)bitmapData.Scan0; fixed (byte* pSourceFixed = &buffer[offset]) { byte* pSource = bitmapDataScan0 + bitmapDataStride * backBufferHeightMinusOne; byte* pDestBuffer = pSourceFixed; for (int y = 0; y < screenCapture.Height; y++) { int* pSourceInt = (int*)pSource; pSourceInt -= (bitmapDataStride * y / 4); int* pDestBufferInt = (int*)pDestBuffer; pDestBufferInt += (backBufferStrideInBytes * y / 4); for (int x = 0; x < screenCapture.Width; x++) { pDestBufferInt[x] = pSourceInt[x]; } } } } bmpScreenCapture.UnlockBits(bitmapData); bmpScreenCapture.Dispose(); return screenCapture; }
internal void UpdateImageBuffer(ImageBuffer destImageBuffer, Bitmap sourceBitmap) { BitmapData bitmapData = null; bool isLocked = false; if (destImageBuffer != null) { if (!isLocked) { bitmapData = sourceBitmap.LockBits(new Rectangle(0, 0, sourceBitmap.Width, sourceBitmap.Height), System.Drawing.Imaging.ImageLockMode.ReadWrite, sourceBitmap.PixelFormat); } int destBufferStrideInBytes = destImageBuffer.StrideInBytes(); int destBufferHeight = destImageBuffer.Height; int destBufferWidth = destImageBuffer.Width; int destBufferHeightMinusOne = destBufferHeight - 1; int bitmapDataStride = bitmapData.Stride; int offset; byte[] buffer = destImageBuffer.GetBuffer(out offset); if (flipY) { unsafe { byte* bitmapDataScan0 = (byte*)bitmapData.Scan0; fixed (byte* pDestFixed = &buffer[offset]) { byte* pSource = bitmapDataScan0; for (int y = 0; y < destBufferHeight; y++) { byte* pDest = pDestFixed + destBufferStrideInBytes * (destBufferHeight - 1 - y); for (int x = 0; x < destBufferWidth; x++) { pDest[x * 4 + 0] = pSource[x * 3 + 0]; pDest[x * 4 + 1] = pSource[x * 3 + 1]; pDest[x * 4 + 2] = pSource[x * 3 + 2]; pDest[x * 4 + 3] = 255; } pSource += bitmapDataStride; } } } } else { unsafe { byte* bitmapDataScan0 = (byte*)bitmapData.Scan0; fixed (byte* pDestFixed = &buffer[offset]) { byte* pSource = bitmapDataScan0; for (int y = 0; y < destBufferHeight; y++) { byte* pDest = pDestFixed + destBufferStrideInBytes * (y); for (int x = 0; x < destBufferWidth; x++) { pDest[x * 4 + 0] = pSource[x * 3 + 0]; pDest[x * 4 + 1] = pSource[x * 3 + 1]; pDest[x * 4 + 2] = pSource[x * 3 + 2]; pDest[x * 4 + 3] = 255; } pSource += bitmapDataStride; } } } } if (!isLocked) { sourceBitmap.UnlockBits(bitmapData); } } }
public void Fill(ImageBuffer bufferToFillOn, int x, int y) { unchecked // this way we can overflow the uint on negative and get a big number { if ((uint)x > bufferToFillOn.Width || (uint)y > bufferToFillOn.Height) { return; } } destImage = bufferToFillOn; imageStride = destImage.StrideInBytes(); destBuffer = destImage.GetBuffer(); int imageWidth = destImage.Width; int imageHeight = destImage.Height; pixelsChecked = new bool[destImage.Width * destImage.Height]; int startColorBufferOffset = destImage.GetBufferOffsetXY(x, y); fillRule.SetStartColor(new RGBA_Bytes(destImage.GetBuffer()[startColorBufferOffset + 2], destImage.GetBuffer()[startColorBufferOffset + 1], destImage.GetBuffer()[startColorBufferOffset])); LinearFill(x, y); while (ranges.Count > 0) { Range range = ranges.Dequeue(); int downY = range.y - 1; int upY = range.y + 1; int downPixelOffset = (imageWidth * (range.y - 1)) + range.startX; int upPixelOffset = (imageWidth * (range.y + 1)) + range.startX; for (int rangeX = range.startX; rangeX <= range.endX; rangeX++) { if (range.y > 0) { if (!pixelsChecked[downPixelOffset]) { int bufferOffset = destImage.GetBufferOffsetXY(rangeX, downY); if (fillRule.CheckPixel(destBuffer, bufferOffset)) { LinearFill(rangeX, downY); } } } if (range.y < (imageHeight - 1)) { if (!pixelsChecked[upPixelOffset]) { int bufferOffset = destImage.GetBufferOffsetXY(rangeX, upY); if (fillRule.CheckPixel(destBuffer, bufferOffset)) { LinearFill(rangeX, upY); } } } upPixelOffset++; downPixelOffset++; } } }
public MarchingSquaresByte(ImageBuffer imageToMarch, PositiveArea0to1 thresholdFunction, int debugColor) { thersholdPerPixel = new double[imageToMarch.Width * imageToMarch.Height]; { byte[] buffer = imageToMarch.GetBuffer(); int strideInBytes = imageToMarch.StrideInBytes(); for (int y = 0; y < imageToMarch.Height; y++) { int imageBufferOffset = imageToMarch.GetBufferOffsetY(y); int thresholdBufferOffset = y * imageToMarch.Width; for (int x = 0; x < imageToMarch.Width; x++) { int imageBufferOffsetWithX = imageBufferOffset + x * 4; thersholdPerPixel[thresholdBufferOffset + x] = thresholdFunction(GetRGBA(buffer, imageBufferOffsetWithX)); } } } this.thresholdFunction = thresholdFunction; this.imageToMarch = imageToMarch; this.debugColor = debugColor; CreateLineSegments(); }