protected virtual void BuildNormalMap(PixelBitmapContent <Single> bm, PixelBitmapContent <Color> n) { unchecked { int ww = n.Width; int hh = n.Height; for (int y = 0; y < hh; ++y) { for (int x = 0; x < ww; ++x) { float v00 = bm.GetPixel(x, y); float v01 = bm.GetPixel(x, y + 1); float v10 = bm.GetPixel(x + 1, y); float v11 = bm.GetPixel(x + 1, y + 1); // 80 meters up/down for the renderer // two dx-es means divide by 2 (to average) // two meters per triangle side means divide by 2 to normalize to meters // That is crappy resolution. I should probably use floats instead of bytes // for the underlying storage pixmap... float ddx = (v10 + v11 - v00 - v01) * Page.DynamicRange * 0.5f * 0.5f; float ddy = (v01 + v11 - v00 - v10) * Page.DynamicRange * 0.5f * 0.5f; Vector3 v = new Vector3(-ddx, -ddy, 1.0f); v.Normalize(); v = v * 0.5f + new Vector3(0.5f, 0.5f, 0.5f); Color c = new Color(v); n.SetPixel(x, y, c); } } } }
private List <Glyph> ExtractGlyphs(PixelBitmapContent <Color> bitmap) { var glyphs = new List <Glyph>(); var regions = new List <Rectangle>(); for (int y = 0; y < bitmap.Height; y++) { for (int x = 0; x < bitmap.Width; x++) { if (bitmap.GetPixel(x, y) != transparentPixel) { // if we don't have a region that has this pixel already var re = regions.Find(r => { return(r.Contains(x, y)); }); if (re == Rectangle.Empty) { // we have found the top, left of a image. // we now need to scan for the 'bounds' int top = y; int bottom = y; int left = x; int right = x; while (bitmap.GetPixel(right, bottom) != transparentPixel) { right++; } while (bitmap.GetPixel(left, bottom) != transparentPixel) { bottom++; } // we got a glyph :) regions.Add(new Rectangle(left, top, right - left, bottom - top)); x = right; } else { x += re.Width; } } } } for (int i = 0; i < regions.Count; i++) { var rect = regions[i]; var newBitmap = new PixelBitmapContent <Color>(rect.Width, rect.Height); BitmapContent.Copy(bitmap, rect, newBitmap, new Rectangle(0, 0, rect.Width, rect.Height)); var glyph = new Glyph(GetCharacterForIndex(i), newBitmap); glyph.CharacterWidths.B = glyph.Bitmap.Width; glyphs.Add(glyph); //newbitmap.Save (GetCharacterForIndex(i)+".png", System.Drawing.Imaging.ImageFormat.Png); } return(glyphs); }
static PixelBitmapContent <Color> CreateAlphaChannel(PixelBitmapContent <Color> input) { int width = input.Width; int height = input.Height; PixelBitmapContent <Color> result = new PixelBitmapContent <Color>(width, height); for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { Color color = input.GetPixel(x, y); // Adds/Replaces Alpha channel with the "Brightest color channel value // A better way would be to average all three colors and use that for alpha. // This will work just fine for grey scale textures and is simpler... byte resultAlpha1 = (byte)(color.PackedValue & 0xff); byte resultAlpha2 = (byte)(color.PackedValue & 0xff00); byte resultAlpha3 = (byte)(color.PackedValue & 0xff0000); byte resultAlpha = Math.Max(Math.Max(resultAlpha1, resultAlpha2), resultAlpha3); color.PackedValue = (uint)(resultAlpha << 24) + (0x00ffffff); result.SetPixel(x, y, color); } } return(result); }
public override TOutput Process(TInput input, ContentProcessorContext context) { input.ConvertBitmapType(typeof(PixelBitmapContent <Vector4>)); PixelBitmapContent <Vector4> bm = (PixelBitmapContent <Vector4>)(((Texture2DContent)input).Mipmaps[0]); for (int y = 0, ym = bm.Height; y != ym; ++y) { for (int x = 0, xm = bm.Width; x != xm; ++x) { Vector4 v = bm.GetPixel(x, y); float w = 1 - v.W; if (v.Z > w) { v.Z = w; } w -= v.Z; if (v.Y > w) { v.Y = w; } w -= v.Y; if (v.X > w) { v.X = w; } System.Diagnostics.Debug.Assert(v.X + v.Y + v.Z + v.W <= 1.001f); // it's OK for w to be > 0 here, as that means the base layer weight bm.SetPixel(x, y, v); } } input.ConvertBitmapType(typeof(PixelBitmapContent <Color>)); input.GenerateMipmaps(true); return(input); }
public override Vertices Process(Texture2DContent input, ContentProcessorContext context) { if (ScaleFactor < 1) { throw new Exception("Pixel to meter ratio must be greater than zero."); } PixelBitmapContent <Color> bitmapContent = (PixelBitmapContent <Color>)input.Faces[0][0]; uint[] colorData = new uint[bitmapContent.Width * bitmapContent.Height]; for (int i = 0; i < bitmapContent.Height; i++) { for (int j = 0; j < bitmapContent.Width; j++) { Color c = bitmapContent.GetPixel(j, i); c.R *= c.A; c.G *= c.A; c.B *= c.A; colorData[i * bitmapContent.Width + j] = c.PackedValue; } } Vertices outline = PolygonUtils.CreatePolygon(colorData, bitmapContent.Width, HoleDetection); Vector2 centroid = -outline.GetCentroid(); outline.Translate(ref centroid); Vector2 scale = new Vector2(_scaleFactor); outline.Scale(ref scale); return(outline); }
/// <summary> /// Generates a terrain mesh from an input heightfield texture. /// </summary> public override TerrainModelContent Process(Texture2DContent input, ContentProcessorContext context) { Texture2DContent texture = context.Convert <Texture2DContent, Texture2DContent>(input, "FloatingPointTextureProcessor"); PixelBitmapContent <float> heightfield = (PixelBitmapContent <float>)texture.Mipmaps[0]; float[,] heights = new float[heightfield.Width, heightfield.Height]; for (int y = 0; y < heightfield.Height; y++) { for (int x = 0; x < heightfield.Width; x++) { heights[x, y] = heightfield.GetPixel(x, y); } } HeightMapContent heightMap = new HeightMapContent(heightfield.Width, heightfield.Height, heights, VerticalScale, HorizontalScale); string directory = Path.GetDirectoryName(input.Identity.SourceFilename); string texture1 = Path.Combine(directory, ColorTexture); string texture2 = Path.Combine(directory, DetailTexture); // Create a material, and point it at our terrain texture. DualTextureMaterialContent material = new DualTextureMaterialContent { Texture = context.BuildAsset <TextureContent, TextureContent>(new ExternalReference <TextureContent>(texture1), null), Texture2 = context.BuildAsset <TextureContent, TextureContent>(new ExternalReference <TextureContent>(texture2), null), }; TerrainModelContentBuilder terrainModelContentBuilder = new TerrainModelContentBuilder(PatchSize, Tau, heightMap, material, DetailTextureTiling, HorizontalScale); return(terrainModelContentBuilder.Build(context)); }
/// <summary> /// Applies a single pass of a separable box filter, blurring either /// along the x or y axis. This could give much higher quality results /// if we used a gaussian filter kernel rather than this simplistic box, /// but this is good enough to get the job done. /// </summary> static void ApplyBlurPass(PixelBitmapContent <Vector4> source, PixelBitmapContent <Vector4> destination, int dx, int dy) { int cubemapCenter = cubemapSize / 2; for (int y = 0; y < cubemapSize; y++) { for (int x = 0; x < cubemapSize; x++) { // How far is this texel from the center of the image? int xDist = cubemapCenter - x; int yDist = cubemapCenter - y; int distance = (int)Math.Sqrt(xDist * xDist + yDist * yDist); // Blur more in the center, less near the edges. int blurAmount = Math.Max(cubemapCenter - distance, 0) / 8; // Accumulate source texel values. Vector4 blurredValue = Vector4.Zero; for (int i = -blurAmount; i <= blurAmount; i++) { blurredValue += source.GetPixel(x + dx * i, y + dy * i); } // Average them to calculate a blurred result. blurredValue /= blurAmount * 2 + 1; destination.SetPixel(x, y, blurredValue); } } }
internal static void WriteTexture(object spriteFontContent, bool alphaOnly, ContentProcessorContext context, string filename) { dynamic sfc = ExposedObject.From(spriteFontContent); // Get a copy of the texture in Color format Texture2DContent originalTexture = sfc.Texture; BitmapContent originalBitmap = originalTexture.Mipmaps[0]; PixelBitmapContent <Color> colorBitmap = new PixelBitmapContent <Color>( originalBitmap.Width, originalBitmap.Height); BitmapContent.Copy(originalBitmap, colorBitmap); Bitmap bitmap = new Bitmap(colorBitmap.Width, colorBitmap.Height, PixelFormat.Format32bppArgb); for (int x = 0; x < colorBitmap.Width; x++) { for (int y = 0; y < colorBitmap.Height; y++) { Color c = colorBitmap.GetPixel(x, y); if (alphaOnly) { c.R = 255; c.G = 255; c.B = 255; // Undo premultiplication } bitmap.SetPixel(x, y, System.Drawing.Color.FromArgb(c.A, c.R, c.G, c.B)); } } bitmap.Save(filename, ImageFormat.Png); bitmap.Dispose(); context.AddOutputFile(filename); }
/// <summary> /// Flattens vectors from a normal map into a 2D displacement map /// and stores them in the RG portion of the bitmap. /// </summary> public static void ConvertNormalsToDisplacement( PixelBitmapContent <NormalizedByte4> bitmap, float distortionScale) { for (int y = 0; y < bitmap.Height; y++) { for (int x = 0; x < bitmap.Width; x++) { // Get the normal from the normal map Vector4 normal4 = bitmap.GetPixel(x, y).ToVector4(); Vector3 normal3 = new Vector3(normal4.X, normal4.Y, normal4.Z); // Determine the magnitude of the distortion at this pixel float amount = Vector3.Dot(normal3, Vector3.Backward) * distortionScale; // Create a displacement vector of that magnitude in the direction // of the normal projected onto the plane of the texture. Vector2 normal2 = new Vector2(normal3.X, normal3.Y); Vector2 displacement = normal2 * amount + new Vector2(.5f, .5f); // Store the result bitmap.SetPixel(x, y, new NormalizedByte4(displacement.X, displacement.Y, 0, 0)); } } }
/// <summary> /// Process converts the encoded normals to the NormalizedByte4 format and /// generates mipmaps. /// </summary> /// <param name="input"></param> /// <param name="context"></param> /// <returns></returns> public override TextureContent Process(TextureContent input, ContentProcessorContext context) { Texture2DContent result = new Texture2DContent(); if (input.Faces[0][0] is PixelBitmapContent <Alpha8> ) { return(input); } input.ConvertBitmapType(typeof(PixelBitmapContent <Vector3>)); PixelBitmapContent <Vector3> source = input.Faces[0][0] as PixelBitmapContent <Vector3>; PixelBitmapContent <Alpha8> bitmap = new PixelBitmapContent <Alpha8>(source.Width, source.Height); for (int y = 0; y < source.Height; ++y) { for (int x = 0; x < source.Width; ++x) { Vector3 src = source.GetPixel(x, y); bitmap.SetPixel(x, y, new Alpha8( 0.3f * src.X + 0.59f * src.Y + 0.11f * src.Z)); } } result.Mipmaps.Add(bitmap); return(result); }
public void BitmapCopyFullResize() { var b1 = new PixelBitmapContent<Color>(8, 8); Fill(b1, Color.Red); var b2 = new PixelBitmapContent<Color>(4, 4); BitmapContent.Copy(b1, b2); for (var y = 0; y < b2.Height; y++) for (var x = 0; x < b2.Width; x++) Assert.AreEqual(Color.Red, b2.GetPixel(x, y)); }
public void BitmapConvertFullNoResize() { var b1 = new PixelBitmapContent<Color>(8, 8); Fill(b1, Color.Red); var b2 = new PixelBitmapContent<Bgr565>(8, 8); BitmapContent.Copy(b1, b2); var packed = new Bgr565(1.0f, 0.0f, 0.0f); for (var y = 0; y < b2.Height; y++) for (var x = 0; x < b2.Width; x++) Assert.AreEqual(packed, b2.GetPixel(x, y)); }
/// <summary> /// Worker function for folding and stretching a flap from the source /// image to make up one quarter of the top or bottom cubemap faces. /// </summary> static void ScaleTrapezoid(PixelBitmapContent <Color> source, int cubeSide, int cubeY, PixelBitmapContent <Color> destination, int destinationX, int destinationY, int xDirection1, int yDirection1, int xDirection2, int yDirection2) { int size = destination.Width; // Compute the source x location. int baseSourceX = cubeSide * source.Width / 4; // Copy the image data one row at a time. for (int row = 0; row < size / 2; row++) { // Compute the source y location. int sourceY; if (cubeY < 0) { sourceY = source.Height / 3; } else { sourceY = source.Height * 2 / 3; } sourceY += cubeY * row * source.Height / 3 / (size / 2); // Stretch this row from the source to destination. int x = destinationX; int y = destinationY; int rowLength = size - row * 2; for (int i = 0; i < rowLength; i++) { int sourceX = baseSourceX + i * source.Width / 4 / rowLength; Color color = source.GetPixel(sourceX, sourceY); destination.SetPixel(x, y, color); x += xDirection1; y += yDirection1; } // Advance to the start of the next row. destinationX += xDirection1 + xDirection2; destinationY += yDirection1 + yDirection2; } }
public HeightMapInfoContent(PixelBitmapContent <float> bitmap, float terrainScale, float terrainBumpiness) { TerrainScale = terrainScale; Height = new float[bitmap.Width, bitmap.Height]; for (var y = 0; y < bitmap.Height; y++) { for (var x = 0; x < bitmap.Width; x++) { Height[x, y] = (bitmap.GetPixel(x, y) - 1) * terrainBumpiness; } } }
public override HeightMapInfoContent Process(Texture2DContent input, ContentProcessorContext context) { MeshBuilder meshBuilder = MeshBuilder.StartMesh("terrain"); input.ConvertBitmapType(typeof(PixelBitmapContent <float>)); PixelBitmapContent <float> item = (PixelBitmapContent <float>)input.Mipmaps[0]; for (int i = 0; i < item.Height; i++) { for (int j = 0; j < item.Width; j++) { Vector3 width = new Vector3( mScale * (j - (item.Width - 1) / 2f), width.Y = (item.GetPixel(j, i) - 1f) * Bumpiness, width.Z = mScale * (i - (item.Height - 1) / 2f) ); meshBuilder.CreatePosition(width); } } BasicMaterialContent basicMaterialContent = new BasicMaterialContent(); basicMaterialContent.SpecularColor = new Vector3(0.4f, 0.4f, 0.4f); if (!string.IsNullOrEmpty(TerrainTexture)) { string directoryName = Path.GetDirectoryName(input.Identity.SourceFilename); string str = Path.Combine(directoryName, TerrainTexture); basicMaterialContent.Texture = new ExternalReference <TextureContent>(str); } meshBuilder.SetMaterial(basicMaterialContent); int num = meshBuilder.CreateVertexChannel <Vector2>(VertexChannelNames.TextureCoordinate(0)); int num1 = 0; while (num1 < item.Height - 1) { for (int k = 0; k < item.Width - 1; k++) { AddVertex(meshBuilder, num, item.Width, k, num1); AddVertex(meshBuilder, num, item.Width, k + 1, num1); AddVertex(meshBuilder, num, item.Width, k + 1, num1 + 1); AddVertex(meshBuilder, num, item.Width, k, num1); AddVertex(meshBuilder, num, item.Width, k + 1, num1 + 1); AddVertex(meshBuilder, num, item.Width, k, num1 + 1); } num1++; } MeshContent meshContent = meshBuilder.FinishMesh(); ModelContent modelContent = context.Convert <MeshContent, ModelContent>(meshContent, "ModelProcessor"); return(new HeightMapInfoContent(modelContent, meshContent, mScale, item.Width, item.Height)); }
public static Color[] getData(this PixelBitmapContent <Color> self) { var data = new Color[self.Width * self.Height]; var i = 0; for (var y = 0; y < self.Height; y++) { for (var x = 0; x < self.Width; x++) { data[i++] = self.GetPixel(x, y); } } return(data); }
static int GetBottom(ref Rectangle rect, PixelBitmapContent <Color> bitmap, Color colorKey) { for (int y = rect.Bottom - 1, i = 0; y >= rect.Top; y--, i++) { for (int x = rect.Left; x < rect.Right; x++) { var color = bitmap.GetPixel(x, y); if (color.A != 0 && color != colorKey) { return(i); } } } return(0); }
public CubeHeightmapContent(PixelBitmapContent<float> bitmap, float unitScale, int blockScale, int altitudeScale) { scale = unitScale * (float) blockScale; var xLength = bitmap.Width; var zLength = bitmap.Height; heights = new float[xLength, zLength]; for (int z = 0; z < zLength; z++) { for (int x = 0; x < xLength; x++) { //Heights[x, z] = altitudeScale * (spriteBitmap.GetPixel(x, z) - 1); int y = (int) (bitmap.GetPixel(x, z) * (float) altitudeScale); Heights[x, z] = y * Scale; } } }
public void BitmapCopyFullResize() { var b1 = new PixelBitmapContent <Color>(8, 8); Fill(b1, Color.Red); var b2 = new PixelBitmapContent <Color>(4, 4); BitmapContent.Copy(b1, b2); for (var y = 0; y < b2.Height; y++) { for (var x = 0; x < b2.Width; x++) { Assert.AreEqual(Color.Red, b2.GetPixel(x, y)); } } }
/// <summary> /// This constructor will initialize the height array from the values in the /// bitmap. Each pixel in the bitmap corresponds to one entry in the height /// array. /// </summary> public HeightMapInfoContent(PixelBitmapContent <float> bitmap, float terrainScale, float terrainBumpiness) { this.terrainScale = terrainScale; height = new float[bitmap.Width, bitmap.Height]; for (int y = 0; y < bitmap.Height; y++) { for (int x = 0; x < bitmap.Width; x++) { // the pixels will vary from 0 (black) to 1 (white). // by subtracting 1, our heights vary from -1 to 0, which we then // multiply by the "bumpiness" to get our final height. height[x, y] = (bitmap.GetPixel(x, y) - 1) * terrainBumpiness; } } }
/// <summary> /// Copies greyscale color information into the alpha channel. /// </summary> static void ConvertGreyToAlpha(PixelBitmapContent <Vector4> bitmap) { for (int y = 0; y < bitmap.Height; y++) { for (int x = 0; x < bitmap.Width; x++) { Vector4 value = bitmap.GetPixel(x, y); // Copy a greyscale version of the RGB data into the alpha channel. float greyscale = (value.X + value.Y + value.Z) / 3; value.W = greyscale; bitmap.SetPixel(x, y, value); } } }
void BitmapCopyFullResize <T>(T color1, IEqualityComparer <T> comparer) where T : struct, IEquatable <T> { var b1 = new PixelBitmapContent <T>(8, 8); Fill(b1, color1); var b2 = new PixelBitmapContent <T>(4, 4); BitmapContent.Copy(b1, b2); for (var y = 0; y < b2.Height; y++) { for (var x = 0; x < b2.Width; x++) { Assert.That(color1, Is.EqualTo(b2.GetPixel(x, y)).Using(comparer)); } } }
void BitmapCopyFullNoResize <T>(T color1) where T : struct, IEquatable <T> { var b1 = new PixelBitmapContent <T>(8, 8); Fill(b1, color1); var b2 = new PixelBitmapContent <T>(8, 8); BitmapContent.Copy(b1, b2); for (var y = 0; y < b2.Height; y++) { for (var x = 0; x < b2.Width; x++) { Assert.AreEqual(color1, b2.GetPixel(x, y)); } } }
public void BitmapCopyRegionResize() { var b1 = new PixelBitmapContent <Color>(8, 8); Fill(b1, Color.Red); var b2 = new PixelBitmapContent <Color>(8, 8); Fill(b2, Color.Blue); BitmapContent.Copy(b1, new Rectangle(0, 0, 4, 4), b2, new Rectangle(0, 0, 3, 6)); for (var y = 0; y < b2.Height; y++) { for (var x = 0; x < b2.Width; x++) { Assert.AreEqual(x < 3 && y < 6 ? Color.Red : Color.Blue, b2.GetPixel(x, y)); } } }
void BitmapCopyRegionResize <T>(T color1, T color2, IEqualityComparer <T> comparer) where T : struct, IEquatable <T> { var b1 = new PixelBitmapContent <T>(8, 8); Fill(b1, color1); var b2 = new PixelBitmapContent <T>(8, 8); Fill(b2, color2); BitmapContent.Copy(b1, new Rectangle(0, 0, 4, 4), b2, new Rectangle(0, 0, 3, 6)); for (var y = 0; y < b2.Height; y++) { for (var x = 0; x < b2.Width; x++) { Assert.That(x < 3 && y < 6 ? color1 : color2, Is.EqualTo(b2.GetPixel(x, y)).Using(comparer)); } } }
void BitmapCopyMoveRegionNoResize <T>(T color1, T color2) where T : struct, IEquatable <T> { var b1 = new PixelBitmapContent <T>(8, 8); Fill(b1, color1); var b2 = new PixelBitmapContent <T>(8, 8); Fill(b2, color2); BitmapContent.Copy(b1, new Rectangle(0, 0, 4, 4), b2, new Rectangle(4, 4, 4, 4)); for (var y = 0; y < b2.Height; y++) { for (var x = 0; x < b2.Width; x++) { Assert.AreEqual(x >= 4 && y >= 4 ? color1 : color2, b2.GetPixel(x, y)); } } }
public void BitmapConvertFullNoResize() { var b1 = new PixelBitmapContent <Color>(8, 8); Fill(b1, Color.Red); var b2 = new PixelBitmapContent <Bgr565>(8, 8); BitmapContent.Copy(b1, b2); var packed = new Bgr565(1.0f, 0.0f, 0.0f); for (var y = 0; y < b2.Height; y++) { for (var x = 0; x < b2.Width; x++) { Assert.AreEqual(packed, b2.GetPixel(x, y)); } } }
}//method public PixelBitmapContent <Rgba1010102> Decode2(PixelBitmapContent <Color> bmpInput) { // Decoded Bitmap PixelBitmapContent <Rgba1010102> bmpDecoded = new PixelBitmapContent <Rgba1010102>(bmpInput.Width, bmpInput.Height); // Convert each pixel to gamma decoded float for (int y = 0; y < bmpInput.Height; y++) { for (int x = 0; x < bmpInput.Width; x++) { // Get Input Pixel Color Cinput = bmpInput.GetPixel(x, y); // Set Output Pixel bmpDecoded.SetPixel(x, y, GammaDecodeColor2(Cinput.ToVector4())); } //for (x) } //for (y) return(bmpDecoded); }
PixelBitmapContent <Rgba1010102> Encode2(PixelBitmapContent <Rgba1010102> bmpMipMap) { // Create Color Bitmap of Equal Size PixelBitmapContent <Rgba1010102> bmpColor = new PixelBitmapContent <Rgba1010102>(bmpMipMap.Width, bmpMipMap.Height); // Convert each pixel to gamma encoded color for (int y = 0; y < bmpMipMap.Height; y++) { for (int x = 0; x < bmpMipMap.Width; x++) { // Get Input Pixel Rgba1010102 CmipMap = bmpMipMap.GetPixel(x, y); // Set Output Pixel bmpColor.SetPixel(x, y, GammaEncodeColor2(CmipMap.ToVector4())); } //for (x) } //for (y) return(bmpColor); }//method
/// <summary> /// Our source data is just a regular 2D image, but to make a good /// cubemap we need this to wrap on all sides without any visible seams. /// An easy way of making an image wrap from left to right is simply to /// put a mirrored copy of the image next to the original. The point /// where the image mirrors is still pretty obvious, but for a reflection /// map this will be good enough. /// </summary> static PixelBitmapContent <Color> MirrorBitmap(PixelBitmapContent <Color> source) { int width = source.Width * 2; PixelBitmapContent <Color> mirrored; mirrored = new PixelBitmapContent <Color>(width, source.Height); for (int y = 0; y < source.Height; y++) { for (int x = 0; x < source.Width; x++) { Color color = source.GetPixel(x, y); mirrored.SetPixel(x, y, color); mirrored.SetPixel(width - x - 1, y, color); } } return(mirrored); }
/// <summary> /// Helper for looking up height values from the bitmap alpha channel, /// clamping if the specified position is off the edge of the bitmap. /// </summary> static float GetHeight(PixelBitmapContent <Vector4> bitmap, int x, int y) { if (x < 0) { x = 0; } else if (x >= bitmap.Width) { x = bitmap.Width - 1; } if (y < 0) { y = 0; } else if (y >= bitmap.Height) { y = bitmap.Height - 1; } return(bitmap.GetPixel(x, y).W); }
public override TextureContent Process(TextureContent input, ContentProcessorContext context) { TextureContent texContent = base.Process(input, context); texContent.ConvertBitmapType(typeof(PixelBitmapContent <Color>)); for (int face = 0; face < input.Faces.Count; face++) { MipmapChain mipChain = input.Faces[face]; for (int mipLevel = 0; mipLevel < mipChain.Count; mipLevel++) { PixelBitmapContent <Color> oldImage = (PixelBitmapContent <Color>)input.Faces[face][mipLevel]; PixelBitmapContent <Color> grayImage = new PixelBitmapContent <Color>(oldImage.Width, oldImage.Height); for (int x = 0; x < oldImage.Width; x++) { for (int y = 0; y < oldImage.Height; y++) { Color oldColor = oldImage.GetPixel(x, y); float grayValue = oldColor.R * 0.299f / 255.0f; grayValue += oldColor.G * 0.596f / 255.0f; grayValue += oldColor.B * 0.211f / 255.0f; float alpha = oldColor.A / 255.0f; Color grayColor = new Color(grayValue, grayValue, grayValue, alpha); Color newColor = Color.Lerp(oldColor, grayColor, interpolation); grayImage.SetPixel(x, y, newColor); } } input.Faces[face][mipLevel] = grayImage; } } return(texContent); }
public override List <Vertices> Process(Texture2DContent input, ContentProcessorContext context) { if (ScaleFactor < 1) { throw new Exception("Pixel to meter ratio must be greater than zero."); } PixelBitmapContent <Color> bitmapContent = (PixelBitmapContent <Color>)input.Faces[0][0]; uint[] colorData = new uint[bitmapContent.Width * bitmapContent.Height]; for (int i = 0; i < bitmapContent.Height; i++) { for (int j = 0; j < bitmapContent.Width; j++) { Color c = bitmapContent.GetPixel(j, i); c.R *= c.A; c.G *= c.A; c.B *= c.A; colorData[i * bitmapContent.Width + j] = c.PackedValue; } } Vertices outline = PolygonUtils.CreatePolygon(colorData, bitmapContent.Width, HoleDetection); Vector2 centroid = -outline.GetCentroid(); outline.Translate(ref centroid); outline = SimplifyTools.DouglasPeuckerSimplify(outline, 0.1f); List <Vertices> result = Triangulate.ConvexPartition(outline, TriangulationAlgorithm.Bayazit); Vector2 scale = new Vector2(_scaleFactor); foreach (Vertices vertices in result) { vertices.Scale(ref scale); } return(result); }
/// <summary> /// 圧縮ブロックの処理 /// </summary> /// <param name="source">元画像</param> /// <param name="blockX">Xブロック位置</param> /// <param name="blockY">Yブロック位置</param> /// <param name="color0">単色カラー</param> /// <param name="outputData">出力先</param> /// <param name="outputIndex">出力オフセット</param> private static void CompressDxt3Block(PixelBitmapContent<Color> source, int blockX, int blockY, ushort color0, byte[] outputData, int outputIndex) { long alphaBits = 0; int rgbBits = 0; int pixelCount = 0; // 4x4ブロック内の処理 for (int y = 0; y < 4; ++y) { for (int x = 0; x < 4; ++x) { // 元のアルファ値の取得 int value = source.GetPixel(blockX + x, blockY + y).A; int alpha = 0; int rgb = 0; // アルファ値によって、出力値を決定。 // ここでは単純にアルファ値領域を4分割するのではなく、6分割にして // 1/6、1/2、5/6の非線形の閾値を使っている if (value < 256 / 6) { alpha = 0; rgb = 1; // c1色 = 0 } else if (value < 256 * 3 / 6) { alpha = 5; rgb = 3; // c3色 = 1/3(c0) + 2/3(c1) = 85 } else if (value < 256 * 5 / 6) { alpha = 10; rgb = 2; // c2色 = 1/2(c0) + 1/2(c1) = 127 } else { alpha = 15; rgb = 0; // c0色 = 255 } // 計算結果ビットを格納 alphaBits |= (long)alpha << (pixelCount * 4); rgbBits |= rgb << (pixelCount * 2); pixelCount++; } } // DXT3ブロック情報の出力 // アルファ 8バイト for (int i = 0; i < 8; ++i) { outputData[outputIndex + i] = (byte)(alphaBits >> (i * 8)); } // カラー値(c0, c1) 4バイト // c0 outputData[outputIndex + 8] = (byte)(color0 & 0xff); outputData[outputIndex + 9] = (byte)((color0 >> 8) & 0xff); // c1 outputData[outputIndex + 10] = 0x00; outputData[outputIndex + 11] = 0x00; // RGB情報 4バイト for (int i = 0; i < 4; ++i) { outputData[outputIndex + 12 + i] = (byte)(rgbBits >> (i * 8)); } }
internal static void WriteTexture(object spriteFontContent, bool alphaOnly, ContentProcessorContext context, string filename) { dynamic sfc = ExposedObject.From(spriteFontContent); // Get a copy of the texture in Color format Texture2DContent originalTexture = sfc.Texture; BitmapContent originalBitmap = originalTexture.Mipmaps[0]; PixelBitmapContent<Color> colorBitmap = new PixelBitmapContent<Color>( originalBitmap.Width, originalBitmap.Height); BitmapContent.Copy(originalBitmap, colorBitmap); Bitmap bitmap = new Bitmap(colorBitmap.Width, colorBitmap.Height, PixelFormat.Format32bppArgb); for(int x = 0; x < colorBitmap.Width; x++) for(int y = 0; y < colorBitmap.Height; y++) { Color c = colorBitmap.GetPixel(x, y); if(alphaOnly) { c.R = 255; c.G = 255; c.B = 255; // Undo premultiplication } bitmap.SetPixel(x, y, System.Drawing.Color.FromArgb(c.A, c.R, c.G, c.B)); } bitmap.Save(filename, ImageFormat.Png); bitmap.Dispose(); context.AddOutputFile(filename); }
public void BitmapCopyMoveRegionNoResize() { var b1 = new PixelBitmapContent<Color>(8, 8); Fill(b1, Color.Red); var b2 = new PixelBitmapContent<Color>(8, 8); Fill(b2, Color.Blue); BitmapContent.Copy(b1, new Rectangle(0, 0, 4, 4), b2, new Rectangle(4, 4, 4, 4)); for (var y = 0; y < b2.Height; y++) for (var x = 0; x < b2.Width; x++) Assert.AreEqual(x >= 4 && y >= 4 ? Color.Red : Color.Blue, b2.GetPixel(x, y)); }