I found a library to work with QR Code in C#.
https://github.com/codebude/QRCoder/
There is a sample to add our logo in QR Code generated image.
I want add my gif logo instead of png logo.
The gif is motion.
My question is: How I can add gif to Bitmap or something like that and save it?
In that library, they used Graphics.DrawImage to set icon in center of the generated QR Code Image.
The code they used is:
public Image GetGraphic(
int pixelsPerModule,
Color darkColor,
Color lightColor,
Bitmap icon = null,
int iconSizePercent = 15,
int iconBorderWidth = 0,
bool drawQuietZones = true,
Color? iconBackgroundColor = null)
{
int num1 = (QrCodeData.ModuleMatrix.Count - (drawQuietZones ? 0 : 8)) * pixelsPerModule;
int num2 = drawQuietZones ? 0 : 4 * pixelsPerModule;
Bitmap graphic = new Bitmap(num1, num1, PixelFormat.Format32bppArgb);
using (Graphics graphics = Graphics.FromImage(graphic))
{
using (SolidBrush solidBrush1 = new SolidBrush(lightColor))
{
using (SolidBrush solidBrush2 = new SolidBrush(darkColor))
{
graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
graphics.CompositingQuality = CompositingQuality.HighQuality;
graphics.Clear(lightColor);
bool flag = icon != null && iconSizePercent > 0 && iconSizePercent <= 100;
for (int index1 = 0; index1 < num1 + num2; index1 += pixelsPerModule)
{
for (int index2 = 0; index2 < num1 + num2; index2 += pixelsPerModule)
{
SolidBrush solidBrush3 = QrCodeData.ModuleMatrix[(index2 + pixelsPerModule) / pixelsPerModule - 1]
[(index1 + pixelsPerModule) / pixelsPerModule - 1] ? solidBrush2 : solidBrush1;
graphics.FillRectangle(solidBrush3, new Rectangle(index1 - num2,
index2 - num2, pixelsPerModule, pixelsPerModule));
}
}
if (flag)
{
float width = (iconSizePercent * graphic.Width) / 100f;
float height = flag ? width * icon.Height / icon.Width : 0.0f;
float x = (float)((graphic.Width - (double)width) / 2.0);
float y = (float)((graphic.Height - (double)height) / 2.0);
RectangleF rect = new RectangleF(x - iconBorderWidth, y - iconBorderWidth,
width + (iconBorderWidth * 2), height + (iconBorderWidth * 2));
RectangleF destRect = new RectangleF(x, y, width, height);
SolidBrush solidBrush4 = iconBackgroundColor.HasValue ? new SolidBrush(iconBackgroundColor.Value) : solidBrush1;
if (iconBorderWidth > 0)
{
using (GraphicsPath roundedRectanglePath = CreateRoundedRectanglePath(rect, iconBorderWidth * 2))
graphics.FillPath(solidBrush4, roundedRectanglePath);
}
graphics.DrawImage(icon, destRect, new RectangleF(0.0f, 0.0f, icon.Width, icon.Height), GraphicsUnit.Pixel);
}
graphics.Save();
}
}
}
return graphic;
}
Related
I have Bitmap Images that are usually smaller than 500x500 pixels.
But sometimes one or both dimensions can exceed 500 pixels.
If the height is >500 I want to crop the image at the bottom and if the width is >500 I want to crop it on both sides equally.
If the Image is <500 in any dimension I want to pad it with white pixels on each side equally to make it 500x500.
I'm not familliar with .NET but I understand there's a lot that'S already been done for you (I'm a C++ developer).
I appreciate any help! Thanks!
This is what I have so far, which puts the image in the center of a white 500x500 rectangular image. It's just that I cant wrap my head around the cases where one dimension of the original image exceeds 500 pixels. (See the two lines with ??)
public static System.Drawing.Bitmap PadImage(System.Drawing.Bitmap originalImage)
{
if (originalImage.Height > 500)
??
if (originalImage.Width > 500)
??
Size squareSize = new Size(500, 500);
System.Drawing.Bitmap squareImage = new System.Drawing.Bitmap(squareSize.Width, squareSize.Height);
using (Graphics graphics = Graphics.FromImage(squareImage))
{
graphics.FillRectangle(System.Drawing.Brushes.White, 0, 0, squareSize.Width, squareSize.Height);
graphics.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
graphics.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
graphics.DrawImage(originalImage, (squareSize.Width / 2) - (originalImage.Width / 2), (squareSize.Height / 2) - (originalImage.Height / 2), originalImage.Width, originalImage.Height);
}
return squareImage;
}
Bitmap PadCropImage(Bitmap original)
{
if (original.Width == 500 && original.Height == 500)
return original;
if (original.Width > 500 && original.Height > 500)
{
int x = (original.Width - 500) / 2;
int y = (original.Height - 500) / 2;
return original.Clone(new Rectangle(x, y, 500, 500), original.PixelFormat);
}
Bitmap square = new Bitmap(500, 500);
var g = Graphics.FromImage(square);
if (original.Width > 500)
{
int x = (original.Width - 500) / 2;
int y = (500 - original.Height) / 2;
g.DrawImageUnscaled(original, -x, y);
}
else if (original.Height > 500)
{
int x = (500 - original.Width) / 2;
int y = (original.Height - 500) / 2;
g.DrawImageUnscaled(original, x, -y);
}
else
{
int x = (500 - original.Width) / 2;
int y = (500 - original.Height) / 2;
g.DrawImageUnscaled(original, x, y);
}
return square;
}
Here is an old method I have used many times
public static Image ThumbnailImage(Image sourceImage, int imageSize, bool maintainAspectRatio, bool maintainImageSize, Color backgroundColor)
{
try
{
int thumbnailWidth = imageSize;
int thumbnailHeight = imageSize;
if (maintainAspectRatio)
{
float aspectRatio = (float) sourceImage.Width/sourceImage.Height;
float targetAspectRatio = (float) thumbnailWidth/thumbnailHeight;
if (aspectRatio < targetAspectRatio)
{
thumbnailWidth = (int) (thumbnailHeight*aspectRatio);
}
else if (aspectRatio > targetAspectRatio)
{
thumbnailHeight = (int) (thumbnailWidth/aspectRatio);
}
}
Image thumbnail = sourceImage.GetThumbnailImage(thumbnailWidth, thumbnailHeight, null, new IntPtr());
if (maintainImageSize)
{
var offset = new Point(0, 0);
if (thumbnailWidth != imageSize)
{
offset.X = ((imageSize - thumbnailWidth)/2);
}
if (thumbnailHeight != imageSize)
{
offset.Y = ((imageSize - thumbnailHeight)/2);
}
var bmpImage = new Bitmap(imageSize, imageSize, PixelFormat.Format32bppArgb);
using (Graphics graphics = Graphics.FromImage(bmpImage))
{
graphics.Clear(backgroundColor);
graphics.DrawImage(thumbnail, new Rectangle(offset.X, offset.Y, thumbnailWidth, thumbnailHeight), new Rectangle(0, 0, thumbnailWidth, thumbnailHeight), GraphicsUnit.Pixel);
}
thumbnail.Dispose();
return Image.FromHbitmap(bmpImage.GetHbitmap());
}
return thumbnail;
}
catch (Exception exception)
{
const string strExMsg = "Error Creating Thumbnail";
throw new Exception(Assembly.GetExecutingAssembly().GetName().Name + " - " + strExMsg + " Msg : " + exception.Message);
}
}
Noob needs help!
I have an image and I need to add noise on it. I tried using AForge libs to do it but this method works only with 24bpp bitmaps and I get something different after resizing. The question is how to convert a bitmap to 24bpp or how to add noise on it? Maybe there are some libs for making this easier.
Resizing:
private Image Fit(Image image)
{
Image img = image;
if (filepath != null)
{
if (img.Width > pictureBox1.Width)
{
double op = ((pictureBox1.Width - (pictureBox1.Width % 100)) % 100) + (pictureBox1.Width % 100) * 0.01;
double percent = img.Width / (pictureBox1.Width * 0.01);
double temp = ((percent - percent % 100 + 100) - percent) * pictureBox1.Height * 0.01;
double height = pictureBox1.Height * 0.01 * ((percent - percent % 100 + 100) - percent);
System.Drawing.Size sz = new Size(pictureBox1.Width, (int)height);
img = resizeImage(img, sz);
}
if (img.Height > pictureBox1.Height)
{
double percent = img.Height / (pictureBox1.Height * 0.01);
double temp = ((percent - percent % 100 + 100) - percent) * pictureBox1.Width * 0.01;
double width = pictureBox1.Width * 0.01 * ((percent - percent % 100 + 100) - percent);
System.Drawing.Size sz = new Size((int)width, pictureBox1.Height);
img = resizeImage(img, sz);
}
}
return img;
}
P.S.> I have a type of bug - system totally refuses to divide 1 by 100 so I had to multiply 1 by 0.01 or I get 0.
Resizing the image to maintain aspect ratio is pretty easy. You compute the horizontal and vertical scaling factors, and then select the smallest of the two.
double vscale = 1.0;
double hscale = 1.0;
if (img.Width > pictureBox1.Width)
{
hscale = (double)pictureBox1.Width/img.Width;
}
if (img.Height > pictureBox1.Height)
{
vscale = (double)pictureBox1.Height/img.Height;
}
double scale = Math.Min(hscale, vscale);
double width = scale * img.Width;
double height = scale * img.Height;
Size sz = new Size((int)width, (int)height);
img = resizeImage(img, sz)
Note that this only scales if the image is larger than the box. It won't zoom the image to make it fit the box if the image is smaller than the box.
Haven't found anything good. That's how I've solved it:
public void GenerateNoise(Image img, int intense)
{
Bitmap finalBmp = img as Bitmap;
Random r = new Random();
int width = img.Width;
int height = img.Height;
for (int x = 0; x < width; x++)
{
for (int y = 0; y < height; y++)
{
int def = r.Next(0, 100);
if (def < intense)
{
int op = r.Next(0, 1);
if (op == 0)
{
int num = r.Next(0, intense);
Color clr = finalBmp.GetPixel(x, y);
int R = (clr.R + clr.R + num)/2;
if (R > 255) R = 255;
int G = (clr.G + clr.G + num) / 2;
if (G > 255) G = 255;
int B = (clr.B + clr.B + num) / 2;
if (B > 255) B = 255;
Color result = Color.FromArgb(255, R, G, B);
finalBmp.SetPixel(x, y, result);
}
else
{
int num = r.Next(0, intense);
Color clr = finalBmp.GetPixel(x, y);
Color result = Color.FromArgb(255, (clr.R + clr.R - num) / 2, (clr.G + clr.G - num) / 2,
(clr.B + clr.B - num) / 2);
finalBmp.SetPixel(x, y, result);
}
}
}
}
}
I have large 500MB size image I want to show this image like map with zoom and pan features in ASP.net. I found OpenLayers for this but anyone can share any working example using any framework/library to achieve this functionality in ASP.net
i found one answer which i like to share with you. here is the code
private static void Split(string fileName, int width, int height)
{
using (Bitmap source = new Bitmap(fileName))
{
bool perfectWidth = source.Width % width == 0;
bool perfectHeight = source.Height % height == 0;
int lastWidth = width;
if (!perfectWidth)
{
lastWidth = source.Width - ((source.Width / width) * width);
}
int lastHeight = height;
if (!perfectHeight)
{
lastHeight = source.Height - ((source.Height / height) * height);
}
int widthPartsCount = source.Width / width + (perfectWidth ? 0 : 1);
int heightPartsCount = source.Height / height + (perfectHeight ? 0 : 1);
for (int i = 0; i < widthPartsCount; i++)
for (int j = 0; j < heightPartsCount; j++)
{
int tileWidth = i == widthPartsCount - 1 ? lastWidth : width;
int tileHeight = j == heightPartsCount - 1 ? lastHeight : height;
using (Bitmap tile = new Bitmap(tileWidth, tileHeight))
{
using (Graphics g = Graphics.FromImage(tile))
{
g.DrawImage(source, new Rectangle(0, 0, tile.Width, tile.Height), new Rectangle(i * width, j * height, tile.Width, tile.Height), GraphicsUnit.Pixel);
}
tile.Save(string.Format("{0}-{1}.png", i + 1, j + 1), ImageFormat.Png);
}
}
}
}
I would advise to make some smaller images(Mipmapping http://en.wikipedia.org/wiki/Mipmap ) or/and cut them in smaller parts. (Slice up an image into tiles)
Think about, you can't see all the pixels of 500mb data. Only transfer what you actually see.
Hello How to draw a circle with the bitmap. That is, I need to get the image of the circle, using it to draw something.
Use ColorTranslator.FromHtml for this purpose.
This will give you the corresponding System.Drawing.Color:
using (Bitmap btm = new Bitmap(25, 30))
{
using (Graphics grf = Graphics.FromImage(btm))
{
using (Brush brsh = new SolidBrush(ColorTranslator.FromHtml("#ff00ffff")))
{
grf.FillEllipse(brsh, 0, 0, 19, 19);
}
}
}
Or Refer Code:
Bitmap bmp = new Bitmap(pictureBox1.Width, pictureBox1.Height);
Graphics g = Graphics.FromImage(bmp);
Pen blackPen = new Pen(Color.Black);
int x = pictureBox1.Width/4;
int y = pictureBox1.Height/4;
int width = pictureBox1.Width / 2;
int height = pictureBox1.Height / 2;
int diameter = Math.Min(width, height);
g.DrawEllipse(blackPen, x, y, diameter, diameter);
pictureBox1.Image = bmp;
If the PictureBox already contains a bitmap, replace the first and second lines with:
Graphics g = Graphics.FromImage(pictureBox1.Image);
Referance Link:
http://www.c-sharpcorner.com/Forums/Thread/30986/
Hope Its Helpful.
Bitmap b = new Bitmap(261, 266);// height & width of picturebox
int xo = 50, yo = 50;// center of circle
double r, rr;
r = 20;
rr = Math.Pow(r, 2);
for (int i = xo - (int)r; i <= xo + r; i++)
for (int j = yo - (int)r; j <= yo + r; j++)
if (Math.Abs(Math.Pow(i - xo, 2) + Math.Pow(j - yo, 2) - rr) <= r)
b.SetPixel(i, j, Color.Black);
pictureBox1.Image = b;
Is there any open source C# code or library to present a graphical waveform given a byte array?
This is as open source as it gets:
public static void DrawNormalizedAudio(ref float[] data, PictureBox pb,
Color color)
{
Bitmap bmp;
if (pb.Image == null)
{
bmp = new Bitmap(pb.Width, pb.Height);
}
else
{
bmp = (Bitmap)pb.Image;
}
int BORDER_WIDTH = 5;
int width = bmp.Width - (2 * BORDER_WIDTH);
int height = bmp.Height - (2 * BORDER_WIDTH);
using (Graphics g = Graphics.FromImage(bmp))
{
g.Clear(Color.Black);
Pen pen = new Pen(color);
int size = data.Length;
for (int iPixel = 0; iPixel < width; iPixel++)
{
// determine start and end points within WAV
int start = (int)((float)iPixel * ((float)size / (float)width));
int end = (int)((float)(iPixel + 1) * ((float)size / (float)width));
float min = float.MaxValue;
float max = float.MinValue;
for (int i = start; i < end; i++)
{
float val = data[i];
min = val < min ? val : min;
max = val > max ? val : max;
}
int yMax = BORDER_WIDTH + height - (int)((max + 1) * .5 * height);
int yMin = BORDER_WIDTH + height - (int)((min + 1) * .5 * height);
g.DrawLine(pen, iPixel + BORDER_WIDTH, yMax,
iPixel + BORDER_WIDTH, yMin);
}
}
pb.Image = bmp;
}
This function will produce something like this:
This takes an array of samples in floating-point format (where all sample values range from -1 to +1). If your original data is actually in the form of a byte[] array, you'll have to do a little bit of work to convert it to float[]. Let me know if you need that, too.
Update: since the question technically asked for something to render a byte array, here are a couple of helper methods:
public float[] FloatArrayFromStream(System.IO.MemoryStream stream)
{
return FloatArrayFromByteArray(stream.GetBuffer());
}
public float[] FloatArrayFromByteArray(byte[] input)
{
float[] output = new float[input.Length / 4];
for (int i = 0; i < output.Length; i++)
{
output[i] = BitConverter.ToSingle(input, i * 4);
}
return output;
}
Update 2: I forgot there's a better way to do this:
public float[] FloatArrayFromByteArray(byte[] input)
{
float[] output = new float[input.Length / 4];
Buffer.BlockCopy(input, 0, output, 0, input.Length);
return output;
}
I'm just so in love with for loops, I guess.
I modified MusiGenesis's solution a little bit.
This gave me a much better result, especially with house music :)
public static Bitmap DrawNormalizedAudio(List<float> data, Color foreColor, Color backColor, Size imageSize)
{
Bitmap bmp = new Bitmap(imageSize.Width, imageSize.Height);
int BORDER_WIDTH = 0;
float width = bmp.Width - (2 * BORDER_WIDTH);
float height = bmp.Height - (2 * BORDER_WIDTH);
using (Graphics g = Graphics.FromImage(bmp))
{
g.Clear(backColor);
Pen pen = new Pen(foreColor);
float size = data.Count;
for (float iPixel = 0; iPixel < width; iPixel += 1)
{
// determine start and end points within WAV
int start = (int)(iPixel * (size / width));
int end = (int)((iPixel + 1) * (size / width));
if (end > data.Count)
end = data.Count;
float posAvg, negAvg;
averages(data, start, end, out posAvg, out negAvg);
float yMax = BORDER_WIDTH + height - ((posAvg + 1) * .5f * height);
float yMin = BORDER_WIDTH + height - ((negAvg + 1) * .5f * height);
g.DrawLine(pen, iPixel + BORDER_WIDTH, yMax, iPixel + BORDER_WIDTH, yMin);
}
}
return bmp;
}
private static void averages(List<float> data, int startIndex, int endIndex, out float posAvg, out float negAvg)
{
posAvg = 0.0f;
negAvg = 0.0f;
int posCount = 0, negCount = 0;
for (int i = startIndex; i < endIndex; i++)
{
if (data[i] > 0)
{
posCount++;
posAvg += data[i];
}
else
{
negCount++;
negAvg += data[i];
}
}
posAvg /= posCount;
negAvg /= negCount;
}
with adapted code from robby and using Graphics.Fill/DrawClosedCurve with antialiasing, I get a pretty good looking result.
here's the code:
using System;
using System.Drawing;
using System.Drawing.Drawing2D;
namespace Soundfingerprinting.Audio.Services
{
public static class AudioVisualizationService
{
public class WaveVisualizationConfiguration
{
public Nullable<Color> AreaColor { get; set; }
public Nullable<Color> EdgeColor { get; set; }
public int EdgeSize { get; set; }
public Nullable<Rectangle> Bounds { get; set; }
public double Overlap { get; set; }
public int Step { get; set; }
}
public static void DrawWave(float[] data, Bitmap bitmap, WaveVisualizationConfiguration config = null)
{
Color areaColor = Color.FromArgb(0x7F87CEFA);// Color.LightSkyBlue; semi transparent
Color edgeColor = Color.DarkSlateBlue;
int edgeSize = 2;
int step = 2;
double overlap = 0.10f; // would better use a windowing function
Rectangle bounds = Rectangle.FromLTRB(0, 0, bitmap.Width, bitmap.Height);
if (config != null)
{
edgeSize = config.EdgeSize;
if (config.AreaColor.HasValue)
areaColor = config.AreaColor.GetValueOrDefault();
if (config.EdgeColor.HasValue)
edgeColor = config.EdgeColor.GetValueOrDefault();
if (config.Bounds.HasValue)
bounds = config.Bounds.GetValueOrDefault();
step = Math.Max(1, config.Step);
overlap = config.Overlap;
}
float width = bounds.Width;
float height = bounds.Height;
using (Graphics g = Graphics.FromImage(bitmap))
{
Pen edgePen = new Pen(edgeColor);
edgePen.LineJoin = LineJoin.Round;
edgePen.Width = edgeSize;
Brush areaBrush = new SolidBrush(areaColor);
float size = data.Length;
PointF[] topCurve = new PointF[(int)width / step];
PointF[] bottomCurve = new PointF[(int)width / step];
int idx = 0;
for (float iPixel = 0; iPixel < width; iPixel += step)
{
// determine start and end points within WAV
int start = (int)(iPixel * (size / width));
int end = (int)((iPixel + step) * (size / width));
int window = end - start;
start -= (int)(overlap * window);
end += (int)(overlap * window);
if (start < 0)
start = 0;
if (end > data.Length)
end = data.Length;
float posAvg, negAvg;
averages(data, start, end, out posAvg, out negAvg);
float yMax = height - ((posAvg + 1) * .5f * height);
float yMin = height - ((negAvg + 1) * .5f * height);
float xPos = iPixel + bounds.Left;
if (idx >= topCurve.Length)
idx = topCurve.Length - 1;
topCurve[idx] = new PointF(xPos, yMax);
bottomCurve[bottomCurve.Length - idx - 1] = new PointF(xPos, yMin);
idx++;
}
PointF[] curve = new PointF[topCurve.Length * 2];
Array.Copy(topCurve, curve, topCurve.Length);
Array.Copy(bottomCurve, 0, curve, topCurve.Length, bottomCurve.Length);
g.InterpolationMode = InterpolationMode.HighQualityBicubic;
g.SmoothingMode = SmoothingMode.AntiAlias;
g.FillClosedCurve(areaBrush, curve, FillMode.Winding, 0.15f);
if (edgeSize > 0)
g.DrawClosedCurve(edgePen, curve, 0.15f, FillMode.Winding);
}
}
private static void averages(float[] data, int startIndex, int endIndex, out float posAvg, out float negAvg)
{
posAvg = 0.0f;
negAvg = 0.0f;
int posCount = 0, negCount = 0;
for (int i = startIndex; i < endIndex; i++)
{
if (data[i] > 0)
{
posCount++;
posAvg += data[i];
}
else
{
negCount++;
negAvg += data[i];
}
}
if (posCount > 0)
posAvg /= posCount;
if (negCount > 0)
negAvg /= negCount;
}
}
}
In NAudio, there is code to draw audio waveforms in both WinForms and WPF. Have a look at the demo projects for examples of how to use it.
I've been a fan of ZedGraph for many years and have used it to display all kinds of data in various projects.
The following sample code graphs an array of doubles varying between -1 and 1:
void DisplayWaveGraph(ZedGraphControl graphControl, double[] waveData)
{
var pane = graphControl.GraphPane;
pane.Chart.Border.IsVisible = false;
pane.Chart.Fill.IsVisible = false;
pane.Fill.Color = Color.Black;
pane.Margin.All = 0;
pane.Title.IsVisible = false;
pane.XAxis.IsVisible = false;
pane.XAxis.Scale.Max = waveData.Length - 1;
pane.XAxis.Scale.Min = 0;
pane.YAxis.IsVisible = false;
pane.YAxis.Scale.Max = 1;
pane.YAxis.Scale.Min = -1;
var timeData = Enumerable.Range(0, waveData.Length)
.Select(i => (double) i)
.ToArray();
pane.AddCurve(null, timeData, waveData, Color.Lime, SymbolType.None);
graphControl.AxisChange();
}
The above sample mimics the style of an audio editor by suppressing the axes and changing the colors to produce the following: