internal static void DoXBlur(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(); byte[] cache = new byte[width]; for (int y = 0; y < height; y++) { int offset = sourceDest.GetBufferOffsetY(y); for (int x = 0; x < width; x++) { cache[x] = buffer[offset + x]; } for (int x = 1; x < width - 1; x++) { int newValue = (cache[x - 1] + cache[x] * 2 + cache[x + 1] + 2) / 4; // the + 2 is so that we will round correctly buffer[offset + x] = (byte)newValue; } } }
private void FixImageColors(ImageBuffer bufferedImage) { // Next we expand the image into an openGL texture int imageWidth = bufferedImage.Width; int imageHeight = bufferedImage.Height; byte[] imageBuffer = bufferedImage.GetBuffer(out _); switch (bufferedImage.BitDepth) { case 32: for (int y = 0; y < imageHeight; y++) { for (int x = 0; x < imageWidth; x++) { int pixelIndex = 4 * (x + y * imageWidth); byte r = imageBuffer[pixelIndex + 2]; byte g = imageBuffer[pixelIndex + 1]; byte b = imageBuffer[pixelIndex + 0]; byte a = imageBuffer[pixelIndex + 3]; imageBuffer[pixelIndex + 0] = r; imageBuffer[pixelIndex + 1] = g; imageBuffer[pixelIndex + 2] = b; imageBuffer[pixelIndex + 3] = a; } } break; default: throw new NotImplementedException(); } }
public static Bitmap ConvertImageToBitmap(ImageBuffer sourceImage) { var bitmap = new Bitmap(sourceImage.Width, sourceImage.Height, PixelFormat.Format32bppArgb); BitmapData bitmapData = bitmap.LockBits(new Rectangle(0, 0, bitmap.Width, bitmap.Height), ImageLockMode.ReadWrite, bitmap.PixelFormat); int destIndex = 0; unsafe { byte[] sourceBuffer = sourceImage.GetBuffer(); byte * pDestBuffer = (byte *)bitmapData.Scan0; int scanlinePadding = bitmapData.Stride - bitmapData.Width * 4; for (int y = 0; y < sourceImage.Height; y++) { int sourceIndex = sourceImage.GetBufferOffsetXY(0, sourceImage.Height - 1 - y); for (int x = 0; x < sourceImage.Width; x++) { pDestBuffer[destIndex++] = sourceBuffer[sourceIndex++]; pDestBuffer[destIndex++] = sourceBuffer[sourceIndex++]; pDestBuffer[destIndex++] = sourceBuffer[sourceIndex++]; pDestBuffer[destIndex++] = sourceBuffer[sourceIndex++]; } destIndex += scanlinePadding; } } bitmap.UnlockBits(bitmapData); return(bitmap); }
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(); }
public void CopyColorBufferToImage(ImageBuffer destImage, RectangleInt viewport) { if (destImage.BitDepth != 32) { throw new Exception("We can only render to 32 bit dest at the moment."); } Byte[] destBuffer = destImage.GetBuffer(); viewport.Bottom = Math.Max(0, Math.Min(destImage.Height, viewport.Bottom)); viewport.Top = Math.Max(0, Math.Min(destImage.Height, viewport.Top)); if (MultiThreaded) { System.Threading.Tasks.Parallel.For(viewport.Bottom, viewport.Height, y => { CopyColorXSpan(destImage, viewport, y, destBuffer); }); } else { for (int y = viewport.Bottom; y < viewport.Height; y++) { CopyColorXSpan(destImage, viewport, y, destBuffer); } } destImage.MarkImageChanged(); }
public void CopyNoramlBufferToImage(ImageBuffer destImage, RectangleInt viewport) { if (destImage.BitDepth != 32) { throw new Exception("We can only render to 32 bit dest at the moment."); } Byte[] destBuffer = destImage.GetBuffer(); viewport.Bottom = Math.Max(0, Math.Min(destImage.Height, viewport.Bottom)); viewport.Top = Math.Max(0, Math.Min(destImage.Height, viewport.Top)); for (int y = viewport.Bottom; y < viewport.Height; y++) { for (int x = viewport.Left; x < viewport.Right; x++) { int bufferOffset = destImage.GetBufferOffsetY(y); // we don't need to set this if we are anti-aliased int totalOffset = bufferOffset + x * 4; destBuffer[totalOffset++] = (byte)((NormalBuffer[x][y].x + 1) * 128); destBuffer[totalOffset++] = (byte)((NormalBuffer[x][y].y + 1) * 128); destBuffer[totalOffset++] = (byte)((NormalBuffer[x][y].z + 1) * 128); destBuffer[totalOffset] = 255; } } destImage.MarkImageChanged(); }
public static ImageBuffer Multiply(this ImageBuffer sourceImage, RGBA_Bytes color) { var outputImage = new ImageBuffer(sourceImage); switch (outputImage.BitDepth) { case 32: int height = outputImage.Height; int width = outputImage.Width; byte[] imageABuffer = outputImage.GetBuffer(); for (int y = 0; y < height; y++) { int offsetA = outputImage.GetBufferOffsetY(y); for (int x = 0; x < width; x++) { imageABuffer[offsetA + 0] = (byte)((imageABuffer[offsetA + 0] * color.blue) / 255); imageABuffer[offsetA + 1] = (byte)((imageABuffer[offsetA + 1] * color.green) / 255); imageABuffer[offsetA + 2] = (byte)((imageABuffer[offsetA + 2] * color.red) / 255); imageABuffer[offsetA + 3] = (byte)((imageABuffer[offsetA + 3] * color.alpha) / 255); offsetA += 4; } } break; default: throw new NotImplementedException(); } return(outputImage); }
public bool IsNewImageReady() { if (newImageRead && Monitor.TryEnter(cameraCopyBufferIntPtr, 1)) { unsafe { int width = currentImage.Width; int height = currentImage.Height; byte[] currentImageBuffer = currentImage.GetBuffer(); int offset = 0; for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { currentImageBuffer[offset] = ((byte *)cameraCopyBufferIntPtr)[offset]; offset++; currentImageBuffer[offset] = ((byte *)cameraCopyBufferIntPtr)[offset]; offset++; currentImageBuffer[offset] = ((byte *)cameraCopyBufferIntPtr)[offset]; offset++; currentImageBuffer[offset++] = 255; } } } newImageRead = false; currentImage.MarkImageChanged(); return(true); } return(false); }
public void CopyColorBufferToImage(ImageBuffer destImage, RectangleInt viewport) { if (destImage.BitDepth != 32) { throw new Exception("We can only render to 32 bit dest at the moment."); } Byte[] destBuffer = destImage.GetBuffer(); viewport.Bottom = Math.Max(0, Math.Min(destImage.Height, viewport.Bottom)); viewport.Top = Math.Max(0, Math.Min(destImage.Height, viewport.Top)); #if MULTI_THREAD System.Threading.Tasks.Parallel.For(viewport.Bottom, viewport.Height, y => // #else for (int y = viewport.Bottom; y < viewport.Height; y++) #endif { for (int x = viewport.Left; x < viewport.Right; x++) { int bufferOffset = destImage.GetBufferOffsetY(y); // we don't need to set this if we are anti-aliased int totalOffset = bufferOffset + x * 4; destBuffer[totalOffset++] = (byte)colorBuffer[x][y].Blue0To255; destBuffer[totalOffset++] = (byte)colorBuffer[x][y].Green0To255; destBuffer[totalOffset++] = (byte)colorBuffer[x][y].Red0To255; destBuffer[totalOffset] = (byte)colorBuffer[x][y].Alpha0To255; } }
private void CheckLineImageCache() { if (aATextureImages == null) { aATextureImages = new List <ImageBuffer>(); for (int i = 0; i < 256; i++) { var texture = new ImageBuffer(1024, 4); aATextureImages.Add(texture); byte[] hardwarePixelBuffer = texture.GetBuffer(); for (int y = 0; y < 4; y++) { byte alpha = 0; for (int x = 0; x < 1024; x++) { hardwarePixelBuffer[(y * 1024 + x) * 4 + 0] = 255; hardwarePixelBuffer[(y * 1024 + x) * 4 + 1] = 255; hardwarePixelBuffer[(y * 1024 + x) * 4 + 2] = 255; hardwarePixelBuffer[(y * 1024 + x) * 4 + 3] = alpha; alpha = (byte)i; } } } } }
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; } } }
private void CalculateDistance(ImageBuffer image) { var maxDist = (image.Height + image.Width) > 255 ? 255 : (image.Height + image.Width); var buffer = image.GetBuffer(); // O(n^2) solution to find the Manhattan distance to "on" pixels in a two dimension array // traverse from top left to bottom right for (int y = 0; y < image.Height; y++) { var yOffset = image.GetBufferOffsetY(y); for (int x = 0; x < image.Width; x++) { if (buffer[yOffset + x] == 0) { // first pass and pixel was off, it remains a zero } else { // pixel was on // It is at most the sum of the lengths of the array // away from a pixel that is off buffer[yOffset + x] = (byte)maxDist; // or one more than the pixel to the north if (x > 0) { var value = Math.Min(buffer[yOffset + x], buffer[yOffset + x - 1] + 1); buffer[yOffset + x] = (byte)value; } // or one more than the pixel to the west if (y > 0) { var value = Math.Min(buffer[yOffset + x], buffer[yOffset - image.Width + x] + 1); buffer[yOffset + x] = (byte)value; } } } } // traverse from bottom right to top left for (int y = image.Height - 1; y >= 0; y--) { var yOffset = image.GetBufferOffsetY(y); for (int x = image.Width - 1; x >= 0; x--) { // either what we had on the first pass // or one more than the pixel to the south if (x + 1 < image.Width) { var value = Math.Min(buffer[yOffset + x], buffer[yOffset + x + 1] + 1); buffer[yOffset + x] = (byte)value; } // or one more than the pixel to the east if (y + 1 < image.Height) { var value = Math.Min(buffer[yOffset + x], buffer[yOffset + image.Width + x] + 1); buffer[yOffset + x] = (byte)value; } } } }
void PlaceObjectsOnLevel() { ImageBuffer levelMap = LevelMap; int offset; byte[] buffer = levelMap.GetBuffer(out offset); for (int y = 0; y < levelMap.Height(); y++) { for (int x = 0; x < levelMap.Width(); x++) { offset = levelMap.GetBufferOffsetXY(x, y); switch (buffer[offset]) { case 220: // this is the sword. sword = new Sword(); sword.Position = new Vector2D(x * 16 + 8, y * 16 + 8); break; case 170: // this is the key. key = new Key(); key.Position = new Vector2D(x * 16 + 8, y * 16 + 8); keyStart = key.Position; break; case 2: // this is the red player. playerList[0].Position = new Vector2D(x * 16 + 8, y * 16 + 8); break; case 35: // this is the green player. playerList[1].Position = new Vector2D(x * 16 + 8, y * 16 + 8); break; case 251: // this is the blue player. playerList[2].Position = new Vector2D(x * 16 + 8, y * 16 + 8); break; case 5: // this is the yellow player. playerList[3].Position = new Vector2D(x * 16 + 8, y * 16 + 8); break; case 248: // this is the shield. shield = new Shield(); shield.Position = new Vector2D(x * 16 + 8, y * 16 + 8); break; default: break; } } } }
public void BuildHistogramFromImage(ImageBuffer image, ImageToPathObject3D_2.AnalysisTypes analysisType) { // build the histogram cache var height = (int)(100 * GuiWidget.DeviceScale); _histogramRawCache = new ImageBuffer(256, height); var counts = new int[_histogramRawCache.Width]; IThresholdFunction function = new MapOnMaxIntensity(0, 1); var bottom = 0; if (analysisType == ImageToPathObject3D_2.AnalysisTypes.Colors) { function = new QuickHue(); bottom = (int)(10 * GuiWidget.DeviceScale); } byte[] buffer = image.GetBuffer(); for (int y = 0; y < image.Height; y++) { int imageBufferOffset = image.GetBufferOffsetY(y); for (int x = 0; x < image.Width; x++) { int imageBufferOffsetWithX = imageBufferOffset + x * 4; var color = GetRGBA(buffer, imageBufferOffsetWithX); counts[(int)(function.Transform(color) * (_histogramRawCache.Width - 1))]++; } } double max = counts.Select((value, index) => new { value, index }) .OrderByDescending(vi => vi.value) .First().value; var graphics = _histogramRawCache.NewGraphics2D(); var theme = ApplicationController.Instance.Theme; graphics.Clear(theme.SlightShade); var graphShape = new VertexStorage(); var graphHeight = height - bottom; graphShape.MoveTo(0, bottom); for (int i = 0; i < 256; i++) { graphShape.LineTo(i, bottom + Easing.Exponential.Out(counts[i] / max) * graphHeight); // graphShape.LineTo(i, bottom + Easing.Cubic.Out(counts[i] / max) * graphHeight); // graphShape.LineTo(i, bottom + Easing.Exponential.Out(counts[i] / max) * graphHeight); // graphShape.LineTo(i, bottom + counts[i] / max * graphHeight); } graphShape.LineTo(256, bottom); graphShape.LineTo(0, bottom); graphics.Render(graphShape, 0, 0, theme.TextColor); for (int i = 0; i < 256; i++) { var hue = ColorF.FromHSL(i / 255.0, 1, .49).ToColor(); graphics.Line(i, 0, i, bottom, hue); } }
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++) { Color minColor = Color.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 static void Remove(ImageBuffer image) { var buffer = image.GetBuffer(); if (imagesWithCacheData.TryGetValue(buffer, out ImageGlPlugin imagePlugin)) { glDataNeedingToBeDeleted.Add(imagePlugin.glData); imagesWithCacheData.Remove(buffer); } }
public override void generate(RGBA_Bytes[] span, int spanIndex, int x, int y, int len) { ImageBuffer SourceRenderingBuffer = (ImageBuffer)GetImageBufferAccessor().SourceImage; int bytesBetweenPixelsInclusive = SourceRenderingBuffer.GetBytesBetweenPixelsInclusive(); if (SourceRenderingBuffer.BitDepth != 8) { throw new NotSupportedException("The source is expected to be 32 bit."); } ISpanInterpolator spanInterpolator = interpolator(); spanInterpolator.begin(x + filter_dx_dbl(), y + filter_dy_dbl(), len); int x_hr; int y_hr; spanInterpolator.coordinates(out x_hr, out y_hr); int x_lr = x_hr >> (int)image_subpixel_scale_e.image_subpixel_shift; int y_lr = y_hr >> (int)image_subpixel_scale_e.image_subpixel_shift; int bufferIndex; bufferIndex = SourceRenderingBuffer.GetBufferOffsetXY(x_lr, y_lr); byte[] fg_ptr = SourceRenderingBuffer.GetBuffer(); #if USE_UNSAFE_CODE unsafe { fixed(byte *pSource = fg_ptr) { do { span[spanIndex].red = pSource[bufferIndex]; span[spanIndex].green = pSource[bufferIndex]; span[spanIndex].blue = pSource[bufferIndex]; span[spanIndex].alpha = 255; spanIndex++; bufferIndex += bytesBetweenPixelsInclusive; } while (--len != 0); } } #else do { throw new Exception("this code is for 32 bit"); RGBA_Bytes color; color.blue = fg_ptr[bufferIndex++]; color.green = fg_ptr[bufferIndex++]; color.red = fg_ptr[bufferIndex++]; color.alpha = fg_ptr[bufferIndex++]; span[spanIndex++] = color; } while (--len != 0); #endif }
public static ImageBuffer AnyAlphaToColor(this ImageBuffer sourceImage, Color color, Color transparency) { var outputImage = new ImageBuffer(sourceImage); switch (outputImage.BitDepth) { case 32: { int height = outputImage.Height; int width = outputImage.Width; byte[] imageABuffer = outputImage.GetBuffer(); for (int y = 0; y < height; y++) { int offsetA = outputImage.GetBufferOffsetY(y); for (int x = 0; x < width; x++) { int alpha = imageABuffer[offsetA + 3]; if (alpha > 0) { // Set semi-transparent colors imageABuffer[offsetA + 0] = color.blue; imageABuffer[offsetA + 1] = color.green; imageABuffer[offsetA + 2] = color.red; //imageABuffer[offsetA + 3] = (byte) (alpha == 255 ? 255 : 255 - alpha); imageABuffer[offsetA + 3] = (byte)alpha; } else { // Set transparent colors imageABuffer[offsetA + 0] = transparency.blue; imageABuffer[offsetA + 1] = transparency.green; imageABuffer[offsetA + 2] = transparency.red; imageABuffer[offsetA + 3] = transparency.alpha; } offsetA += 4; } } //outputImage.SetRecieveBlender(new BlenderPreMultBGRA()); } break; default: throw new NotImplementedException(); } return(outputImage); }
public static void DoAllWhite(ImageBuffer result, ImageBuffer imageA) { if (imageA.BitDepth != result.BitDepth) { throw new NotImplementedException("All the images have to be the same bit depth."); } if (imageA.Width != result.Width || imageA.Height != result.Height) { throw new Exception("All images must be the same size."); } switch (imageA.BitDepth) { case 32: { int height = imageA.Height; int width = imageA.Width; byte[] resultBuffer = result.GetBuffer(); byte[] imageABuffer = imageA.GetBuffer(); for (int y = 0; y < height; y++) { int offsetA = imageA.GetBufferOffsetY(y); int offsetResult = result.GetBufferOffsetY(y); for (int x = 0; x < width; x++) { int alpha = imageABuffer[offsetA + 3]; if (alpha > 0) { resultBuffer[offsetResult++] = (byte)255; offsetA++; resultBuffer[offsetResult++] = (byte)255; offsetA++; resultBuffer[offsetResult++] = (byte)255; offsetA++; resultBuffer[offsetResult++] = (byte)alpha; offsetA++; } else { resultBuffer[offsetResult++] = (byte)0; offsetA++; resultBuffer[offsetResult++] = (byte)0; offsetA++; resultBuffer[offsetResult++] = (byte)0; offsetA++; resultBuffer[offsetResult++] = (byte)0; offsetA++; } } } result.SetRecieveBlender(new BlenderPreMultBGRA()); } break; default: throw new NotImplementedException(); } }
public override void OnParentChanged(EventArgs e) { AnchorAll(); string img_name = "spheres.bmp"; if (!ImageIO.LoadImageData(img_name, image_resample.m_SourceImage)) { string buf; buf = "File not found: " + img_name + ".bmp" + ". Download http://www.antigrain.com/" + img_name + ".bmp" + "\n" + "or copy it from another directory if available."; throw new NotImplementedException(buf); } else { if (image_resample.m_SourceImage.BitDepth != 32) { throw new Exception("we are expecting 32 bit source."); } // give the image some alpha. [4/6/2009 lbrubaker] ImageBuffer image32 = new ImageBuffer(image_resample.m_SourceImage.Width, image_resample.m_SourceImage.Height, 32, new BlenderBGRA()); int offset; byte[] source = image_resample.m_SourceImage.GetBuffer(out offset); byte[] dest = image32.GetBuffer(out offset); for (int y = 0; y < image32.Height; y++) { for (int x = 0; x < image32.Width; x++) { int i = y * image32.Width + x; dest[i * 4 + 0] = source[i * 4 + 0]; dest[i * 4 + 1] = source[i * 4 + 1]; dest[i * 4 + 2] = source[i * 4 + 2]; Vector2 pixel = new Vector2(x, y); Vector2 center = new Vector2(image32.Width / 2, image32.Height / 2); Vector2 delta = pixel - center; int length = (int)Math.Min(delta.Length * 3, 255); dest[i * 4 + 3] = (byte)length; } } // and set our new image with alpha image_resample.m_SourceImage = image32; //image_resample_application.m_SourceImage.SetBlender(new BlenderBGR()); } base.OnParentChanged(e); }
public static void DoThreshold(ImageBuffer result, ImageBuffer sourceImage, int threshold, TestThreshold testFunction) { if (sourceImage.BitDepth != result.BitDepth) { throw new NotImplementedException("All the images have to be the same bit depth."); } if (sourceImage.Width != result.Width || sourceImage.Height != result.Height) { throw new Exception("All images must be the same size."); } switch (sourceImage.BitDepth) { case 32: { int height = sourceImage.Height; int width = sourceImage.Width; byte[] resultBuffer = result.GetBuffer(); byte[] sourceBuffer = sourceImage.GetBuffer(); for (int y = 0; y < height; y++) { int offset = sourceImage.GetBufferOffsetY(y); for (int x = 0; x < width; x++) { if (testFunction(sourceBuffer, offset, threshold)) { resultBuffer[offset + 0] = (byte)255; resultBuffer[offset + 1] = (byte)255; resultBuffer[offset + 2] = (byte)255; resultBuffer[offset + 3] = (byte)255; } else { resultBuffer[offset + 0] = (byte)0; resultBuffer[offset + 1] = (byte)0; resultBuffer[offset + 2] = (byte)0; resultBuffer[offset + 3] = (byte)0; } offset += 4; } } } break; default: throw new NotImplementedException(); } }
public void loadFromImageBuffer(ImageBuffer TextureBitmap, string name = null, bool mipmap = true) { //get the data out of the bitmap byte[] buf = TextureBitmap.GetBuffer(); //Code to get the data to the OpenGL Driver GL.Enable(EnableCap.Texture2D); GL.ActiveTexture(TextureUnit.Texture0); //tell OpenGL that this is a 2D texture GL.BindTexture(TextureTarget.Texture2D, _glTextureID); //the following code sets certian parameters for the texture // GL.TexEnv (TextureEnvTarget.TextureEnv, TextureEnvParameter.TextureEnvMode, (float)TextureEnvMode.Combine); // GL.TexEnv (TextureEnvTarget.TextureEnv, TextureEnvParameter.CombineRgb, (float)TextureEnvMode.Modulate); GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (float)TextureMagFilter.Linear); // this assumes mipmaps are present... GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (float)TextureMinFilter.LinearMipmapLinear); // tell OpenGL to build mipmaps out of the bitmap data // .. what a mess ... http://www.g-truc.net/post-0256.html // this is the old way, must be called before texture is loaded, see below for new way... // GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.GenerateMipmap, (float)1.0f); // tell openGL the next line begins on a word boundary... GL.PixelStore(PixelStoreParameter.UnpackAlignment, 4); // load the texture GL.TexImage2D( TextureTarget.Texture2D, 0, // level PixelInternalFormat.Rgba, TextureBitmap.Width, TextureBitmap.Height, 0, // border PixelFormat.Bgra, // why is this Bgr when the lockbits is rgb!? PixelType.UnsignedByte, buf ); //Console.WriteLine("SSTexture: loaded alpha ({0},{1}) from: {2}", TextureBitmap.Width, TextureBitmap.Height, name); // this is the new way to generate mipmaps if (mipmap) { GL.GenerateMipmap(GenerateMipmapTarget.Texture2D); } }
public static void DoSubtract(ImageBuffer result, ImageBuffer imageToSubtractFrom, ImageBuffer imageToSubtract) { if (lookupSubtractAndClamp == null) { CreateLookup(); } if (imageToSubtractFrom.BitDepth != imageToSubtract.BitDepth || imageToSubtract.BitDepth != result.BitDepth) { throw new NotImplementedException("All the images have to be the same bit depth."); } if (imageToSubtractFrom.Width != imageToSubtract.Width || imageToSubtractFrom.Height != imageToSubtract.Height || imageToSubtractFrom.Width != result.Width || imageToSubtractFrom.Height != result.Height) { throw new Exception("All images must be the same size."); } switch (imageToSubtractFrom.BitDepth) { case 32: { int height = imageToSubtractFrom.Height; int width = imageToSubtractFrom.Width; byte[] resultBuffer = result.GetBuffer(); byte[] imageABuffer = imageToSubtractFrom.GetBuffer(); byte[] imageBBuffer = imageToSubtract.GetBuffer(); for (int y = 0; y < height; y++) { int offset = imageToSubtractFrom.GetBufferOffsetY(y); for (int x = 0; x < width; x++) { resultBuffer[offset] = (byte)lookupSubtractAndClamp[imageABuffer[offset] - imageBBuffer[offset] + 255]; // add 255 to make sure not < 0 offset++; resultBuffer[offset] = (byte)lookupSubtractAndClamp[imageABuffer[offset] - imageBBuffer[offset] + 255]; offset++; resultBuffer[offset] = (byte)lookupSubtractAndClamp[imageABuffer[offset] - imageBBuffer[offset] + 255]; offset++; resultBuffer[offset] = 255; offset++; } } } break; default: throw new NotImplementedException(); } }
public static void DoSetGrayToColor(ImageBuffer result, ImageBuffer imageA, Color color) { if (imageA.BitDepth != result.BitDepth) { throw new NotImplementedException("All the images have to be the same bit depth."); } if (imageA.Width != result.Width || imageA.Height != result.Height) { throw new Exception("All images must be the same size."); } switch (imageA.BitDepth) { case 32: { int height = imageA.Height; int width = imageA.Width; byte[] resultBuffer = result.GetBuffer(); byte[] imageABuffer = imageA.GetBuffer(); for (int y = 0; y < height; y++) { int offsetA = imageA.GetBufferOffsetY(y); int offsetResult = result.GetBufferOffsetY(y); for (int x = 0; x < width; x++) { imageA.GetPixel(x, y).ToColorF().GetHSL(out double _, out double s, out double _); if (s < .01) { resultBuffer[offsetResult++] = (byte)(color.blue); offsetA++; resultBuffer[offsetResult++] = (byte)(color.green); offsetA++; resultBuffer[offsetResult++] = (byte)(color.red); offsetA++; resultBuffer[offsetResult++] = imageABuffer[offsetA++]; } else { offsetResult += 4; offsetA += 4; } } } } break; default: throw new NotImplementedException(); } }
public void CompareToLionTGA() { LionShape lionShape = new LionShape(); ImageBuffer renderedImage = new ImageBuffer(512, 400, 24, new BlenderBGR()); byte alpha = (byte)(.1 * 255); for (int i = 0; i < lionShape.NumPaths; i++) { lionShape.Colors[i].Alpha0To255 = alpha; } Affine transform = Affine.NewIdentity(); transform *= Affine.NewTranslation(-lionShape.Center.x, -lionShape.Center.y); transform *= Affine.NewTranslation(renderedImage.Width / 2, renderedImage.Height / 2); // This code renders the lion: VertexSourceApplyTransform transformedPathStorage = new VertexSourceApplyTransform(lionShape.Path, transform); Graphics2D renderer = renderedImage.NewGraphics2D(); renderer.Clear(new RGBA_Floats(1.0, 1.0, 1.0, 1.0)); renderer.Render(transformedPathStorage, lionShape.Colors, lionShape.PathIndex, lionShape.NumPaths); ImageTgaIO.Save(renderedImage, "TestOutput.tga"); Stream imageStream = File.Open("LionRenderMaster.tga", FileMode.Open); ImageBuffer masterImage = new ImageBuffer(); ImageTgaIO.LoadImageData(masterImage, imageStream, 24); bool sameWidth = masterImage.Width == renderedImage.Width; bool sameHeight = masterImage.Height == renderedImage.Height; Assert.IsTrue(sameWidth && sameHeight); Assert.IsTrue(masterImage.BitDepth == renderedImage.BitDepth); int unused; byte[] masterBuffer = masterImage.GetBuffer(out unused); byte[] renderedBuffer = renderedImage.GetBuffer(out unused); Assert.IsTrue(masterBuffer.Length == renderedBuffer.Length); for (int i = 0; i < masterBuffer.Length; i++) { if (masterBuffer[i] != renderedBuffer[i]) { Assert.IsTrue(false); } } }
public static ImageBuffer ReplaceColor(this ImageBuffer sourceImage, Color existingColor, Color newColor, bool keepExistingAlpha = true) { var outputImage = new ImageBuffer(sourceImage); switch (outputImage.BitDepth) { case 32: { int height = outputImage.Height; int width = outputImage.Width; byte[] imageABuffer = outputImage.GetBuffer(); for (int y = 0; y < height; y++) { int offsetA = outputImage.GetBufferOffsetY(y); for (int x = 0; x < width; x++) { if (imageABuffer[offsetA + 0] == existingColor.blue && imageABuffer[offsetA + 1] == existingColor.green && imageABuffer[offsetA + 2] == existingColor.red && imageABuffer[offsetA + 3] == existingColor.alpha) { // Set transparent colors imageABuffer[offsetA + 0] = newColor.blue; imageABuffer[offsetA + 1] = newColor.green; imageABuffer[offsetA + 2] = newColor.red; if (!keepExistingAlpha) { imageABuffer[offsetA + 3] = newColor.alpha; } } offsetA += 4; } } outputImage.SetRecieveBlender(new BlenderPreMultBGRA()); } break; default: throw new NotImplementedException(); } return(outputImage); }
public void CopyDepthBufferToImage(ImageBuffer destImage, RectangleInt viewport) { if (destImage.BitDepth != 32) { throw new Exception("We can only render to 32 bit dest at the moment."); } byte[] destBuffer = destImage.GetBuffer(); viewport.Bottom = Math.Max(0, Math.Min(destImage.Height, viewport.Bottom)); viewport.Top = Math.Max(0, Math.Min(destImage.Height, viewport.Top)); double minZ = 5000; double maxZ = 0; for (int y = viewport.Bottom; y < viewport.Height; y++) { for (int x = viewport.Left; x < viewport.Right; x++) { double depthAtXY = DepthBuffer[x][y]; if (depthAtXY < 5000) { minZ = Math.Min(minZ, depthAtXY); maxZ = Math.Max(maxZ, depthAtXY); } } } double divisor = maxZ - minZ; if (MultiThreaded) { System.Threading.Tasks.Parallel.For(viewport.Bottom, viewport.Height, y => { CopyDepthXSpan(destImage, viewport, y, destBuffer, minZ, divisor); }); } else { for (int y = viewport.Bottom; y < viewport.Height; y++) { CopyDepthXSpan(destImage, viewport, y, destBuffer, minZ, divisor); } destImage.MarkImageChanged(); } }
public static ImageBuffer AllWhite(this ImageBuffer sourceImage) { var destImage = new ImageBuffer(sourceImage); switch (destImage.BitDepth) { case 32: { int height = destImage.Height; int width = destImage.Width; byte[] resultBuffer = sourceImage.GetBuffer(); byte[] imageABuffer = destImage.GetBuffer(); for (int y = 0; y < height; y++) { int offsetA = destImage.GetBufferOffsetY(y); int offsetResult = sourceImage.GetBufferOffsetY(y); for (int x = 0; x < width; x++) { int alpha = imageABuffer[offsetA + 3]; if (alpha > 0) { resultBuffer[offsetResult++] = (byte)255; offsetA++; resultBuffer[offsetResult++] = (byte)255; offsetA++; resultBuffer[offsetResult++] = (byte)255; offsetA++; resultBuffer[offsetResult++] = (byte)alpha; offsetA++; } else { resultBuffer[offsetResult++] = (byte)0; offsetA++; resultBuffer[offsetResult++] = (byte)0; offsetA++; resultBuffer[offsetResult++] = (byte)0; offsetA++; resultBuffer[offsetResult++] = (byte)0; offsetA++; } } } destImage.SetRecieveBlender(new BlenderPreMultBGRA()); } break; default: throw new NotImplementedException(); } return(destImage); }
private ImageBuffer FixImageSizePower2IfRequired(ImageBuffer bufferedImage) { // Next we expand the image into an openGL texture int imageWidth = bufferedImage.Width; int imageHeight = bufferedImage.Height; byte[] imageBuffer = bufferedImage.GetBuffer(out _); int hardwareWidth = SmallestHardwareCompatibleTextureSize(imageWidth); int hardwareHeight = SmallestHardwareCompatibleTextureSize(imageHeight); var pow2BufferedImage = new ImageBuffer(hardwareWidth, hardwareHeight, 32, bufferedImage.GetRecieveBlender()); pow2BufferedImage.NewGraphics2D().Render(bufferedImage, 0, 0); // always return a new image because we are going to modify its colors and don't want to change the original image return(pow2BufferedImage); }