public override void Perform(Pixmap pixmap, PreviewImageQuery query) { Point2 desiredSize = new Point2(query.DesiredWidth, query.DesiredHeight); Point2 cropToSize = new Point2(4096, 4096); PixelData layer = pixmap.MainLayer; if (layer == null) { query.Result = new Bitmap(1, 1); return; } // If the desired preview is way smaller than the source data, specify a crop size if (layer.Width > desiredSize.X * 8) { cropToSize.X = Math.Min(cropToSize.X, desiredSize.X * 8); } if (layer.Height > desiredSize.Y * 8) { cropToSize.Y = Math.Min(cropToSize.Y, desiredSize.Y * 8); } // If out image is too big, crop it if (layer.Width > cropToSize.X || layer.Height > cropToSize.Y) { layer = layer.CloneSubImage( layer.Width / 2 - MathF.Min(layer.Width, cropToSize.X) / 2, layer.Height / 2 - MathF.Min(layer.Height, cropToSize.Y) / 2, MathF.Min(layer.Width, cropToSize.X), MathF.Min(layer.Height, cropToSize.Y)); } // Determine the target size for the preview based on desired and actual size Point2 targetSize; float widthRatio = (float)layer.Width / (float)MathF.Max(layer.Height, 1); if (query.SizeMode == PreviewSizeMode.FixedWidth) { targetSize = new Point2(desiredSize.X, MathF.RoundToInt(desiredSize.X / widthRatio)); } else if (query.SizeMode == PreviewSizeMode.FixedHeight) { targetSize = new Point2(MathF.RoundToInt(widthRatio * desiredSize.Y), desiredSize.Y); } else { targetSize = desiredSize; } // Create a properly resized version of the image data if (layer.Width != targetSize.X || layer.Height != targetSize.Y) { layer = layer.CloneRescale(targetSize.X, targetSize.Y, ImageScaleFilter.Linear); } query.Result = layer.ToBitmap(); }
public static Bitmap GetPreviewImage(object obj, int desiredWidth, int desiredHeight, PreviewSizeMode mode = PreviewSizeMode.FixedNone) { if (desiredWidth <= 0) return null; if (desiredHeight <= 0) return null; PreviewImageQuery query = new PreviewImageQuery(obj, desiredWidth, desiredHeight, mode); GetPreview(query); return query.Result; }
public override void Perform(AudioData audio, PreviewImageQuery query) { int desiredWidth = query.DesiredWidth; int desiredHeight = query.DesiredHeight; int oggHash = audio.OggVorbisData.GetCombinedHashCode(); int oggLen = audio.OggVorbisData.Length; PcmData pcm = OggVorbis.LoadChunkFromMemory(audio.OggVorbisData, 500000); short[] sdata = pcm.data; short maxVal = 1; for (int i = 0; i < pcm.dataLength; i++) { maxVal = Math.Max(maxVal, Math.Abs(pcm.data[i])); } Bitmap result = new Bitmap(desiredWidth, desiredHeight); int channelLength = pcm.dataLength / pcm.channelCount; int yMid = result.Height / 2; int stepWidth = (channelLength / (2 * result.Width)) - 1; const int samples = 10; using (Graphics g = Graphics.FromImage(result)) { Color baseColor = ExtMethodsColor.ColorFromHSV( (float)(oggHash % 90) * (float)(oggLen % 4) / 360.0f, 0.5f, 1f); Pen linePen = new Pen(Color.FromArgb(MathF.RoundToInt(255.0f / MathF.Pow((float)samples, 0.65f)), baseColor)); g.Clear(Color.Transparent); for (int x = 0; x < result.Width; x++) { float invMaxVal = 2.0f / ((float)maxVal + (float)short.MaxValue); float timePercentage = (float)x / (float)result.Width; int i = MathF.RoundToInt(timePercentage * channelLength); float left; float right; short channel1; short channel2; for (int s = 0; s <= samples; s++) { int offset = stepWidth * s / samples; channel1 = sdata[(i + offset) * pcm.channelCount + 0]; channel2 = sdata[(i + offset) * pcm.channelCount + 1]; left = (float)Math.Abs(channel1) * invMaxVal; right = (float)Math.Abs(channel2) * invMaxVal; g.DrawLine(linePen, x, yMid, x, yMid + MathF.RoundToInt(left * yMid)); g.DrawLine(linePen, x, yMid, x, yMid - MathF.RoundToInt(right * yMid)); } } } query.Result = result; }
public override void Perform(AudioData audio, PreviewImageQuery query) { int desiredWidth = query.DesiredWidth; int desiredHeight = query.DesiredHeight; int oggHash = audio.OggVorbisData.GetCombinedHashCode(); int oggLen = audio.OggVorbisData.Length; Duality.OggVorbis.PcmData pcm = Duality.OggVorbis.OV.LoadFromMemory(audio.OggVorbisData, 1000000); //41236992 short[] sdata = new short[pcm.data.Length / 2]; Buffer.BlockCopy(pcm.data, 0, sdata, 0, pcm.data.Length); Bitmap result = new Bitmap(desiredWidth, desiredHeight); int channelLength = sdata.Length / pcm.channelCount; int yMid = result.Height / 2; int stepWidth = (channelLength / (2 * result.Width)) - 1; const int samples = 10; using (Graphics g = Graphics.FromImage(result)) { Color baseColor = ExtMethodsSystemDrawingColor.ColorFromHSV( (float)(oggHash % 90) * (float)(oggLen % 4) / 360.0f, 0.5f, 1f); Pen linePen = new Pen(Color.FromArgb(MathF.RoundToInt(255.0f / MathF.Pow((float)samples, 0.65f)), baseColor)); g.Clear(Color.Transparent); for (int x = 0; x < result.Width; x++) { float timePercentage = (float)x / (float)result.Width; int i = MathF.RoundToInt(timePercentage * channelLength); float left; float right; short channel1; short channel2; for (int s = 0; s <= samples; s++) { int offset = MathF.RoundToInt((float)stepWidth * (float)s / (float)samples); channel1 = sdata[(i + offset) * pcm.channelCount + 0]; channel2 = sdata[(i + offset) * pcm.channelCount + 1]; left = (float)Math.Abs((int)channel1) / (float)short.MaxValue; right = (float)Math.Abs((int)channel2) / (float)short.MaxValue; g.DrawLine(linePen, x, yMid, x, yMid + MathF.RoundToInt(left * yMid)); g.DrawLine(linePen, x, yMid, x, yMid - MathF.RoundToInt(right * yMid)); } } } query.Result = result; }
public override void Perform(Pixmap pixmap, PreviewImageQuery query) { int desiredWidth = query.DesiredWidth; int desiredHeight = query.DesiredHeight; PixelData layer = pixmap.MainLayer; if (layer == null) { query.Result = new Bitmap(1, 1); return; } float widthRatio = (float)layer.Width / (float)layer.Height; if (pixmap.Width * pixmap.Height > 4096 * 4096) { layer = layer.CloneSubImage( pixmap.Width / 2 - Math.Min(desiredWidth, pixmap.Width) / 2, pixmap.Height / 2 - Math.Min(desiredHeight, pixmap.Height) / 2, Math.Min(desiredWidth, pixmap.Width), Math.Min(desiredHeight, pixmap.Height)); if (layer.Width != desiredWidth || layer.Height != desiredHeight) { layer = layer.CloneRescale(desiredWidth, desiredHeight, ImageScaleFilter.Linear); } } else if (query.SizeMode == PreviewSizeMode.FixedBoth) { layer = layer.CloneRescale(desiredWidth, desiredHeight, ImageScaleFilter.Linear); } else if (query.SizeMode == PreviewSizeMode.FixedWidth) { layer = layer.CloneRescale(desiredWidth, MathF.RoundToInt(desiredWidth / widthRatio), ImageScaleFilter.Linear); } else if (query.SizeMode == PreviewSizeMode.FixedHeight) { layer = layer.CloneRescale(MathF.RoundToInt(widthRatio * desiredHeight), desiredHeight, ImageScaleFilter.Linear); } else { layer = layer.Clone(); } query.Result = layer.ToBitmap(); }
public override void Perform(Font font, PreviewImageQuery query) { int desiredWidth = query.DesiredWidth; int desiredHeight = query.DesiredHeight; const string text = "/acThe quick brown fox jumps over the lazy dog."; FormattedText formatText = new FormattedText(); formatText.MaxWidth = Math.Max(1, desiredWidth - 10); formatText.MaxHeight = Math.Max(1, desiredHeight - 10); formatText.WordWrap = FormattedText.WrapMode.Word; formatText.Fonts = new[] { new ContentRef <Font>(font) }; formatText.ApplySource(text); PixelData textLayer = new PixelData(desiredWidth, MathF.RoundToInt(formatText.Size.Y)); formatText.RenderToBitmap(text, textLayer, 5, 0); Bitmap resultBitmap = textLayer.ToBitmap(); // Debug Font metrics //const bool drawDebugFontMetrics = true; //if (drawDebugFontMetrics) //{ // var metrics = formatText.TextMetrics; // Color fgColor = Color.White; // Color baseLineColor = Color.FromArgb(255, 0, 0); // Color bodyAscentColor = Color.FromArgb(0, 192, 0); // Color ascentColor = Color.FromArgb(64, 64, 255); // Color descentColor = Color.FromArgb(255, 0, 255); // using (Graphics g = Graphics.FromImage(resultBitmap)) // { // for (int i = 0; i < metrics.LineCount; i++) // { // Rect lineBounds = metrics.LineBounds[i]; // g.DrawRectangle(new Pen(Color.FromArgb(128, fgColor)), lineBounds.X + 5, lineBounds.Y, lineBounds.W, lineBounds.H - 1); // g.DrawLine(new Pen(Color.FromArgb(192, baseLineColor)), 0, lineBounds.Y + font.BaseLine, resultBitmap.Width, lineBounds.Y + font.BaseLine); // g.DrawLine(new Pen(Color.FromArgb(192, bodyAscentColor)), 0, lineBounds.Y + font.BaseLine - font.BodyAscent, resultBitmap.Width, lineBounds.Y + font.BaseLine - font.BodyAscent); // g.DrawLine(new Pen(Color.FromArgb(192, ascentColor)), 0, lineBounds.Y + font.BaseLine - font.Ascent, resultBitmap.Width, lineBounds.Y + font.BaseLine - font.Ascent); // g.DrawLine(new Pen(Color.FromArgb(192, descentColor)), 0, lineBounds.Y + font.BaseLine + font.Descent, resultBitmap.Width, lineBounds.Y + font.BaseLine + font.Descent); // } // } //} query.Result = resultBitmap.Resize(desiredWidth, desiredHeight, Alignment.Left); }
public override void Perform(Sprite sprite, PreviewImageQuery query) { int desiredWidth = query.DesiredWidth; int desiredHeight = query.DesiredHeight; var pixMap = sprite.Material.Res?.MainTexture.Res?.BasePixmap.Res; PixelData data = pixMap?.MainLayer; if (data == null) { return; } float widthRatio = (float)data.Width / (float)data.Height; data = data.CloneSubImage((int)sprite.UVRect.X, (int)sprite.UVRect.Y, (int)sprite.UVRect.W, (int)sprite.UVRect.H); //data.Rescale(desiredWidth, (int)desiredHeight * widthRatio); query.Result = data.ToBitmap(); }
public override void Perform(Tileset tileset, PreviewImageQuery query) { int desiredWidth = query.DesiredWidth; int desiredHeight = query.DesiredHeight; TilesetRenderInput input = tileset.RenderConfig.FirstOrDefault(c => c.SourceData != null); Pixmap mainPixmap = (input != null) ? input.SourceData.Res : null; PixelData layer = (mainPixmap != null) ? mainPixmap.MainLayer : null; if (layer == null) { query.Result = new Bitmap(1, 1); return; } float widthRatio = (float)layer.Width / (float)layer.Height; layer = layer.CloneSubImage(0, 0, desiredWidth * 2, desiredHeight * 2); layer.Rescale(desiredWidth, desiredHeight); query.Result = layer.ToBitmap(); }