|
|
it's perfect! thx a lot.
IT Consultant and ISV company owner.
.net developer
|
|
|
|
|
Hello,
I have used this and it works brilliantly. But, now what I want to do is, remove the watermark and get the actual image back again.
Thanx in advance.
Plz help me out.
|
|
|
|
|
Hi,
I have made a little bit of refactoring of this code.
I have removed some parts of code too, so it is not 100% compatible, but it should be ok for most of developers.
Watermark image should has transparency background to work well in this code.
Big thanks to original poster!
using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.Drawing.Drawing2D;
using System.IO;
namespace ConsoleApplication1
{
class Program
{
[STAThread]
static void Main(string[] args)
{
new Program().MakeWatermark("Radoslav Katreniak - watermark text",
@"c:\img\OriginalImage.png",
@"c:\img\LogoIcon.png",
@"c:\img\ResultImage.png",
0.5f);
}
private void MakeWatermark(string copyrightText, string originalImagePath, string watermarkImagePath, string resultImagePath, float alpha)
{
Image originalImage = CreateOriginalImage(originalImagePath);
Image watermarkImage = CreateWaretmarkImage(watermarkImagePath);
Bitmap resultImage = CreateResultImage(originalImage);
Graphics resultGraphics = CreateResultGraphics(resultImage);
InsertOriginalImage(originalImage, resultGraphics);
InsertMessage(originalImage, resultGraphics, copyrightText);
InsertWatermarkImage(watermarkImage, resultGraphics, alpha);
SaveResultImage(resultImage, resultImagePath);
Cleanup(originalImage, watermarkImage, resultImage, resultGraphics);
}
private void InsertOriginalImage(Image originalImage, Graphics resultGraphics)
{
resultGraphics.DrawImage(
originalImage,
new Rectangle(0, 0, originalImage.Width, originalImage.Height),
0,
0,
originalImage.Width,
originalImage.Height,
GraphicsUnit.Pixel);
}
private void InsertMessage(Image originalImage, Graphics resultGraphics, string copyrightText)
{
Font fontType;
SizeF fontSize;
CalculateFontAndSizeOfText(copyrightText, originalImage, resultGraphics, out fontType, out fontSize);
int bottonSpace = (int)(originalImage.Height * .02);
float textPositionY = ((originalImage.Height - bottonSpace) - (fontSize.Height / 2));
float centerOfImgX = (originalImage.Width / 2);
StringFormat strFormat = new StringFormat();
strFormat.Alignment = StringAlignment.Center;
DrawWhitePartOfText(copyrightText, resultGraphics, fontType, textPositionY, centerOfImgX, strFormat);
DrawShadowPartOfText(copyrightText, resultGraphics, fontType, textPositionY, centerOfImgX, strFormat);
}
private void InsertWatermarkImage(Image watermarkImage, Graphics resultGraphics, float alpha)
{
ImageAttributes imageAttributes = CreateImageAttributes(alpha);
Rectangle warermarkPosition = new Rectangle(10, 10, watermarkImage.Width, watermarkImage.Height);
resultGraphics.DrawImage(watermarkImage,
warermarkPosition,
0,
0,
watermarkImage.Width,
watermarkImage.Height,
GraphicsUnit.Pixel,
imageAttributes);
}
private ImageAttributes CreateImageAttributes(float alpha)
{
ImageAttributes imageAttributes = new ImageAttributes();
float[][] colorMatrixElements = {
new float[] {1.0f, 0.0f, 0.0f, 0.0f, 0.0f},
new float[] {0.0f, 1.0f, 0.0f, 0.0f, 0.0f},
new float[] {0.0f, 0.0f, 1.0f, 0.0f, 0.0f},
new float[] {0.0f, 0.0f, 0.0f, alpha, 0.0f},
new float[] {0.0f, 0.0f, 0.0f, 0.0f, 1.0f}};
ColorMatrix wmColorMatrix = new ColorMatrix(colorMatrixElements);
imageAttributes.SetColorMatrix(wmColorMatrix, ColorMatrixFlag.Default, ColorAdjustType.Bitmap);
return imageAttributes;
}
private void CalculateFontAndSizeOfText(string copyrightText, Image originalImage, Graphics grPhoto, out Font fontType, out SizeF fontSize)
{
fontType = null;
fontSize = new SizeF();
for (int fontSizeNum = 100; fontSizeNum > 1; fontSizeNum -= 2)
{
fontType = new Font("arial", fontSizeNum, FontStyle.Bold);
fontSize = grPhoto.MeasureString(copyrightText, fontType);
bool isTextWidthTooBig = (ushort)fontSize.Width > (ushort)(originalImage.Width * 0.98f);
bool isTextHeightTooBig = (ushort)fontSize.Height > (ushort)(originalImage.Height * 0.04f);
if (isTextWidthTooBig || isTextHeightTooBig)
{
continue;
}
break;
}
}
private void DrawWhitePartOfText(string copyrightText, Graphics resultGraphics, Font fontType, float textPositionY, float centerOfImgX, StringFormat strFormat)
{
SolidBrush semiTransBrush = new SolidBrush(Color.FromArgb(153, 0, 0, 0));
resultGraphics.DrawString(copyrightText,
fontType,
semiTransBrush,
new PointF(centerOfImgX + 1, textPositionY + 1),
strFormat);
}
private void DrawShadowPartOfText(string copyrightText, Graphics resultGraphics, Font fontType, float textPositionY, float centerOfImgX, StringFormat strFormat)
{
SolidBrush semiTransBrush = new SolidBrush(Color.FromArgb(153, 255, 255, 255));
resultGraphics.DrawString(copyrightText,
fontType,
semiTransBrush,
new PointF(centerOfImgX, textPositionY),
strFormat);
}
private void SaveResultImage(Bitmap resultImage, string resultImageName)
{
resultImage.Save(resultImageName, ImageFormat.Png);
}
private Image CreateOriginalImage(string imageName)
{
Image originalImage = Image.FromFile(imageName);
return originalImage;
}
private Image CreateWaretmarkImage(string watermarkImageName)
{
Image watermarkImage = new Bitmap(watermarkImageName);
return watermarkImage;
}
private Bitmap CreateResultImage(Image originalImage)
{
Bitmap resultImage = new Bitmap(originalImage.Width, originalImage.Height, PixelFormat.Format24bppRgb);
resultImage.SetResolution(originalImage.HorizontalResolution, originalImage.VerticalResolution);
return resultImage;
}
private static Graphics CreateResultGraphics(Bitmap resultImage)
{
Graphics resultGraphics = Graphics.FromImage(resultImage);
resultGraphics.SmoothingMode = SmoothingMode.AntiAlias;
return resultGraphics;
}
private void Cleanup(Image originalImage, Image watermarkImage, Bitmap resultImage, Graphics resultGraphics)
{
resultImage.Dispose();
originalImage.Dispose();
resultGraphics.Dispose();
watermarkImage.Dispose();
}
}
}
BR,
Radoslav Katreniak
|
|
|
|
|
Thanks for the refactoring. Is it possible to set the watermark on the fly, that is not to save the image in the physical directory?
|
|
|
|
|
One thing. You should catch exceptions to make the code more smart.
|
|
|
|
|
This tutorial has proven to be quite useful to me. Thank you for taking the time to write this.
|
|
|
|
|
Thanks for the article. This helps me a lot. I will use this code for my applications.
|
|
|
|
|
Hello,
First, thank for sharing our article.
I have try on test images and it's work most of the time.
I have encounter an error "GDI error" and I have change imgPhoto.Save(destFileName, ImageFormat.Jpeg); by Bitmap bm = new Bitmap(imgPhoto) and it works.
But sometime, I have an 'Out of memory' exception on this new line of code and I cannot find any solution.
The input image are more than 250MB.
If anybody have an brilliant idea ?
Regards.
Edit: resolved with
using (Stream s = File.OpenRead(@"\myfile.jpg"))
Bitmap _backImage = (Bitmap)Bitmap.FromStream(s);
modified 15-Feb-13 8:38am.
|
|
|
|
|
Thanks for sharing this wonderful tutorial.
|
|
|
|
|
Great article and code!
regards
Hallvard
|
|
|
|
|
Wonderful. I wanna use it on my website. Thanks.
|
|
|
|
|
Great article. Thanks so much. You saved my day
|
|
|
|
|
I modified slightly to make a class and added it to my App_Code. I didn't use the Copyright, only because I didn't need it.
From the codebehind I do this
BasePath = "~/aFileInMySolution/";
PhotoFilename = "origImage.jpg";
WatermarkFilename = "anImageLogo.png";
Copyright = "Copyright 2011";
WatermarkMyImage myImage = new WatermarkMyImage();
string newFileName = myImage.AddWatermarkLayer(Server.MapPath(BasePath), PhotoFilename, WatermarkFilename, Copyright);
backgroundPath = System.Web.VirtualPathUtility.ToAbsolute(BasePath + newFileName);
Here's the method in my WatermarkMyImage class:
public string AddWatermarkLayer(string basePath, string photoFilename, string watermarkFilename, string copyrightString)
{
//Create the image object from the path
System.Drawing.Image imgPhoto = System.Drawing.Image.FromFile(basePath + photoFilename);
//Get the dimensions of imgPhoto
int phWidth = imgPhoto.Width;
int phHeight = imgPhoto.Height;
//Create a new object from the imgPhoto
Bitmap bmPhoto = new Bitmap(phWidth, phHeight, System.Drawing.Imaging.PixelFormat.Format24bppRgb);
bmPhoto.SetResolution(72, 72);
Graphics grPhoto = Graphics.FromImage(bmPhoto);
//Load the watermark image saved as .bmp and set with background color of green (Alpha=0, R=106, G=125, B=106)
System.Drawing.Image imgWatermark = System.Drawing.Image.FromFile(basePath + watermarkFilename);
//Size of imgWatermark
int wmWidth = imgWatermark.Width;
int wmHeight = imgWatermark.Height;
//Draws the imgPhoto to the graphics object position at (x-0, y=0) 100% of original
grPhoto.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
grPhoto.DrawImage(imgPhoto, new Rectangle(0, 0, phWidth, phHeight), 0, 0, phWidth, phHeight, GraphicsUnit.Pixel);
//To maximize the size of the Logo text using seven different fonts
int[] sizes = new int[] { 16, 14, 12, 10, 8, 6, 4 };
Font crFont = null;
SizeF crSize = new SizeF();
//Determines the largest possible size of the font
for (int i = 0; i < 7; i++)
{
crFont = new Font("arial", sizes[i], FontStyle.Bold);
crSize = grPhoto.MeasureString(copyrightString, crFont);
if ((ushort)crSize.Width < (ushort)phWidth)
break;
}
//For photos with varying heights, determines a five percent position from bottom of image
int yPixlesFromBottom = (int)(phHeight * .05);
float yPosFromBottom = (int)((phHeight - yPixlesFromBottom) - (crSize.Height / 2));
float xCenterOfImg = (phWidth / 2);
StringFormat StrFormat = new StringFormat();
StrFormat.Alignment = StringAlignment.Center;
//Create a brush with 60% Black (Alpha 153)
SolidBrush semiTransparBrushOne = new SolidBrush(Color.FromArgb(153, 0, 0, 0));
//Creates a shadow effect
grPhoto.DrawString(copyrightString, crFont, semiTransparBrushOne, new PointF(xCenterOfImg + 1, yPosFromBottom + 1), StrFormat);
//Create a brush with 60% White (Alpha 153)
SolidBrush semiTransparBrushTwo = new SolidBrush(Color.FromArgb(153, 255, 255, 255));
//Draws the same text on top of the previous
grPhoto.DrawString(copyrightString, crFont, semiTransparBrushTwo, new PointF(xCenterOfImg + 1, yPosFromBottom + 1), StrFormat);
//Set the above into a bitmap
Bitmap bmWatermark = new Bitmap(bmPhoto);
bmWatermark.SetResolution(imgPhoto.HorizontalResolution, imgPhoto.VerticalResolution);
Graphics grWatermark = Graphics.FromImage(bmWatermark);
//Apply two color manipulations for the watermark
ImageAttributes imageAttributes = new ImageAttributes();
ColorMap colorMap = new ColorMap();
colorMap.OldColor = Color.FromArgb(255, 0, 255, 0);
colorMap.NewColor = Color.FromArgb(0, 0, 0, 0);
System.Drawing.Imaging.ColorMap[] remapTable = { colorMap };
imageAttributes.SetRemapTable(remapTable, ColorAdjustType.Bitmap);
//Change the opacity of watermark by setting 3rd row, 3rd col to .3f
float[][] colorMatrixElements = {
new float[] {1.0f, 0.0f, 0.0f, 0.0f, 0.0f},
new float[] {0.0f, 1.0f, 0.0f, 0.0f, 0.0f},
new float[] {0.0f, 0.0f, 1.0f, 0.0f, 0.0f},
new float[] {0.0f, 0.0f, 0.0f, 0.3f, 0.0f},
new float[] {0.0f, 0.0f, 0.0f, 0.0f, 1.0f}
};
ColorMatrix wmColorMatrix = new ColorMatrix(colorMatrixElements);
imageAttributes.SetColorMatrix(wmColorMatrix, ColorMatrixFlag.Default, ColorAdjustType.Bitmap);
//Draw the watermark in the upper right hand corner of photo
int xPosOfWm = ((phWidth - wmWidth) - 10);
int yPosOfWm = 10;
grWatermark.DrawImage(imgWatermark, new Rectangle(xPosOfWm, yPosOfWm, wmWidth, wmHeight), 0, 0, wmWidth, wmHeight, GraphicsUnit.Pixel, imageAttributes);
//Finally, replace the original image with new
imgPhoto = bmWatermark;
grPhoto.Dispose();
grWatermark.Dispose();
//Save as original name but concatenate _watermarked to it
string newFilename = "watermarked_" + photoFilename;
imgPhoto.Save(basePath + newFilename, ImageFormat.Jpeg);
imgWatermark.Dispose();
imgPhoto.Dispose();
return newFilename;
}
Thank you so much!
|
|
|
|
|
|
Greetings,
I am currently working on a watermarking application. I am considering a perceptual and non-perceptual watermarks. The thing I am hesitating on is the choice of programming language. Is C# good for such application in general? I am not very familiar whether I can do low-level programming with C#, as compared with C++? What would you suggest?
Regards!
|
|
|
|
|
http://www.codeproject.com/KB/GDI-plus/watermark.aspx/?fid=8753&df=90&mpp=25&sort=Position&tid=3611895
i used the watermark example given on the page,,. i working but image i uploaded is getting blurred,. can i avoid it,.
|
|
|
|
|
How can I apply watermark settings to a printer, so that each page will print with that watermark?
Please help
|
|
|
|
|
Simple and direct! Great!
|
|
|
|
|
The watermark text flows from left buttom corner to right top corner?
DesignerInCore
|
|
|
|
|
|
Brilliant piece of code, i am using this for watermaring, but without the text feature, that is in my watermark image
|
|
|
|
|
HI friends ,
CAN I SET IMAGE OVER VEDIO AT CENTER.......
i AM UNABLE TO DO THIS
PLZ HELP ME
MY CODE FOR COPY LOGO.......
// HERE N IS VALUE OR LINE NUMBER BUT INSTEAD OF THIS I HAVE TO USE X, Y CORDINATES FOR SET LOGO IN CENTER........
lock (this)
{
if (m_bmdLogo != null)
{
int N = 15;
IntPtr ipSource = m_bmdLogo.Scan0;
IntPtr ipDest = (IntPtr)(pBuffer.ToInt32() + (320 * 4) * N);
for (int x = 0; x < m_bmdLogo.Height; x++)
{
CopyMemory(ipDest, ipSource, ((uint)m_bmdLogo.Stride));
// Marshal.Copy(ipDest, savedArray, 0, ipSource);
ipDest = ((IntPtr)(ipDest.ToInt32() + stride));
//BufferLen=
ipSource = ((IntPtr)(ipSource.ToInt32() + m_bmdLogo.Stride));
//ipSource = ((IntPtr)(ipSource.ToInt32() + BufferLen));
}
}
}
|
|
|
|
|
hi friends,
I am working an desktop application IN C# .NET in which I want use water marking functionality... I have done this but there is a problem in showing text or image as water marking in currect way. whatever i want show as water marking in my vedio it is coming in after vertical flip .
***********<u>I want to show image or text AS IT IS NOT FLIPED </u>*********
CODE which I am using.................PLZ HELP WHERE IT IS CREATING PROBLEM
/****************************************************************************
While the underlying libraries are covered by LGPL, this sample is released
as public domain. It is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE.
*****************************************************************************/
using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.Runtime.InteropServices;
using System.Diagnostics;
using DirectShowLib;
namespace DxLogo
{
/// <summary> Summary description for MainForm. </summary>
///
internal class Capture : ISampleGrabberCB, IDisposable
//internal class Capture : IDisposable
{
#region Member variables
/// <summary> graph builder interface. </summary>
private IFilterGraph2 m_FilterGraph = null;
IMediaControl m_mediaCtrl = null;
/// <summary> Set by async routine when it captures an image </summary>
private bool m_bRunning = false;
/// <summary> Dimensions of the image, calculated once in constructor. </summary>
private int m_videoWidth;
private int m_videoHeight;
private int m_stride;
public static string FileName;
BitmapData m_bmdLogo = null;
Bitmap m_Bitmap = null;
#if DEBUG
// Allow you to "Connect to remote graph" from GraphEdit
DsROTEntry m_rot = null;
#endif
#endregion
#region API
[DllImport("Kernel32.dll", EntryPoint = "RtlMoveMemory")]
private static extern void CopyMemory(IntPtr Destination, IntPtr Source, [MarshalAs(UnmanagedType.U4)] uint Length);
#endregion
/// zero based device index, and some device parms, plus the file name to save to
public Capture(int iDeviceNum, int iFrameRate, int iWidth, int iHeight, string FileName)
{
DsDevice[] capDevices;
// Get the collection of video devices
capDevices = DsDevice.GetDevicesOfCat(FilterCategory.VideoInputDevice);
if (iDeviceNum + 1 > capDevices.Length)
{
throw new Exception("No video capture devices found at that index!");
}
try
{
// Set up the capture graph
SetupGraph( capDevices[iDeviceNum], iFrameRate, iWidth, iHeight, FileName);
}
catch
{
Dispose();
throw;
}
}
/// <summary> release everything. </summary>
public void Dispose()
{
CloseInterfaces();
if (m_Bitmap != null)
{
m_Bitmap.UnlockBits(m_bmdLogo);
m_Bitmap = null;
m_bmdLogo = null;
}
}
// Destructor
~Capture()
{
CloseInterfaces();
}
/// <summary> capture the next image </summary>
public void Start()
{
if (!m_bRunning)
{
int hr = m_mediaCtrl.Run();
DsError.ThrowExceptionForHR( hr );
m_bRunning = true;
}
}
// Pause the capture graph.
// Running the graph takes up a lot of resources. Pause it when it
// isn't needed.
public void Pause()
{
if (m_bRunning)
{
int hr = m_mediaCtrl.Pause();
DsError.ThrowExceptionForHR( hr );
m_bRunning = false;
}
}
/// <summary> Specify the logo file to write onto each frame </summary>
public void SetLogo(string fileName)
{
//public Bitmap WaterMarkToImage(string fileName, string Filenameasp)
////{
// Bitmap bmp;
//bmp = new Bitmap(fileName);
// Graphics graphicsObject;
// int x, y;
//try
//{ //create graphics object from bitmap
//graphicsObject = Graphics.FromImage(bmp);
//}
// catch (Exception e)
//{
//Bitmap bmpNew = new Bitmap(bmp.Width, bmp.Height);
// graphicsObject = Graphics.FromImage(bmpNew);
// graphicsObject.DrawImage(bmp, new Rectangle(0, 0, bmpNew.Width, bmpNew.Height), 0, 0, bmp.Width, bmp.Height, GraphicsUnit.Pixel);
// bmp = bmpNew;
//}
// int startsize = (bmp.Width / Filenameasp.Length);
//get the font size with respect to length of the string
//x and y cordinates to draw a string
//x = 0;
//y = bmp.Height / 2;
// y = 0;
// System.Drawing.StringFormat drawFormat = new System.Drawing.StringFormat(StringFormatFlags.DirectionVertical); -> draws a vertical string for watermark
//System.Drawing.StringFormat drawFormat = new System.Drawing.StringFormat(StringFormatFlags.NoWrap);
//drawing string on Image
//graphicsObject.DrawString(Filenameasp, new Font("Verdana", startsize, FontStyle.Bold), new SolidBrush(Color.FromArgb(60, 255, 255, 255)), x, y, drawFormat);
//return a water marked image
//return (bmp);
// }
lock (this)
{
if (fileName.Length > 0)
{
Bitmap m_Bitmap = new Bitmap(fileName);
Rectangle r = new Rectangle(0, 0, m_Bitmap.Width, m_Bitmap.Height);
//m_Bitmap.LockBits(r, ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);
m_bmdLogo = m_Bitmap.LockBits(r, ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);
// m_Bitmap.SetResolution(imgPhoto.HorizontalResolution, imgPhoto.VerticalResolution);
}
else
{
if (m_Bitmap != null)
{
m_Bitmap.UnlockBits(m_bmdLogo);
m_Bitmap = null;
m_bmdLogo = null;
}
}
}
}
/// <summary> build the capture graph for grabber. </summary>
private void SetupGraph(DsDevice dev, int iFrameRate, int iWidth, int iHeight, string FileName)
{
int hr;
ISampleGrabber sampGrabber = null;
IBaseFilter baseGrabFlt = null;
IBaseFilter capFilter = null;
IBaseFilter muxFilter = null;
IFileSinkFilter fileWriterFilter = null;
ICaptureGraphBuilder2 capGraph = null;
// Get the graphbuilder object
m_FilterGraph = new FilterGraph() as IFilterGraph2;
m_mediaCtrl = m_FilterGraph as IMediaControl;
#if DEBUG
m_rot = new DsROTEntry(m_FilterGraph);
#endif
try
{
// Get the ICaptureGraphBuilder2
capGraph = (ICaptureGraphBuilder2) new CaptureGraphBuilder2();
// Get the SampleGrabber interface
sampGrabber = (ISampleGrabber) new SampleGrabber();
// Start building the graph
hr = capGraph.SetFiltergraph( m_FilterGraph );
DsError.ThrowExceptionForHR( hr );
// Add the video device
hr = m_FilterGraph.AddSourceFilterForMoniker(dev.Mon, null, dev.Name, out capFilter);
DsError.ThrowExceptionForHR( hr );
baseGrabFlt = (IBaseFilter) sampGrabber;
ConfigureSampleGrabber(sampGrabber);
// Add the frame grabber to the graph
hr = m_FilterGraph.AddFilter(baseGrabFlt, "Ds.NET Grabber");
DsError.ThrowExceptionForHR(hr);
// If any of the default config items are set
//if (iFrameRate + iHeight + iWidth > 0)
if (iFrameRate> 0)
{
SetConfigParms(capGraph, capFilter, iFrameRate, iWidth, iHeight);
}
// Create a filter for the output avi file
hr = capGraph.SetOutputFileName(MediaSubType.Avi, FileName, out muxFilter, out fileWriterFilter);
DsError.ThrowExceptionForHR( hr );
// Connect everything together
hr = capGraph.RenderStream( PinCategory.Capture, MediaType.Video, capFilter, baseGrabFlt, muxFilter);
DsError.ThrowExceptionForHR( hr );
// Now that sizes are fixed, store the sizes
SaveSizeInfo(sampGrabber);
}
finally
{
if (fileWriterFilter != null)
{
Marshal.ReleaseComObject(fileWriterFilter);
fileWriterFilter = null;
}
if (muxFilter != null)
{
Marshal.ReleaseComObject(muxFilter);
muxFilter = null;
}
if (capFilter != null)
{
Marshal.ReleaseComObject(capFilter);
capFilter = null;
}
if (sampGrabber != null)
{
Marshal.ReleaseComObject(sampGrabber);
sampGrabber = null;
}
}
}
/// <summary> Read and store the properties </summary>
private void SaveSizeInfo(ISampleGrabber sampGrabber)
{
int hr;
// Get the media type from the SampleGrabber
AMMediaType media = new AMMediaType();
hr = sampGrabber.GetConnectedMediaType( media );
DsError.ThrowExceptionForHR( hr );
if( (media.formatType != FormatType.VideoInfo) || (media.formatPtr == IntPtr.Zero) )
{
throw new NotSupportedException( "Unknown Grabber Media Format" );
}
// Grab the size info
VideoInfoHeader videoInfoHeader = (VideoInfoHeader) Marshal.PtrToStructure( media.formatPtr, typeof(VideoInfoHeader) );
m_videoWidth = videoInfoHeader.BmiHeader.Width;
m_videoHeight = videoInfoHeader.BmiHeader.Height;
m_stride = (m_videoWidth * (videoInfoHeader.BmiHeader.BitCount / 8));
DsUtils.FreeAMMediaType(media);
media = null;
}
/// <summary> Set the options on the sample grabber </summary>
private void ConfigureSampleGrabber(ISampleGrabber sampGrabber)
{
int hr;
AMMediaType media = new AMMediaType();
// Set the media type to Video/RBG24
media.majorType = MediaType.Video;
media.subType = MediaSubType.RGB24;
media.formatType = FormatType.VideoInfo;
hr = sampGrabber.SetMediaType( media );
DsError.ThrowExceptionForHR( hr );
DsUtils.FreeAMMediaType(media);
media = null;
// Configure the samplegrabber callback
hr = sampGrabber.SetCallback( this, 1 );
DsError.ThrowExceptionForHR( hr );
}
// Set the Framerate, and video size
private void SetConfigParms(ICaptureGraphBuilder2 capGraph, IBaseFilter capFilter, int iFrameRate, int iWidth, int iHeight)
{
int hr;
object o;
AMMediaType media;
IAMStreamConfig videoStreamConfig;
IAMVideoControl videoControl = capFilter as IAMVideoControl;
// Find the stream config interface
hr = capGraph.FindInterface(
PinCategory.Capture, MediaType.Video, capFilter, typeof(IAMStreamConfig).GUID, out o );
videoStreamConfig = o as IAMStreamConfig;
try
{
if (videoStreamConfig == null)
{
throw new Exception("Failed to get IAMStreamConfig");
}
hr = videoStreamConfig.GetFormat(out media);
DsError.ThrowExceptionForHR( hr );
// copy out the videoinfoheader
VideoInfoHeader v = new VideoInfoHeader();
Marshal.PtrToStructure( media.formatPtr, v );
// if overriding the framerate, set the frame rate
if (iFrameRate > 0)
{
v.AvgTimePerFrame = 10000000 / iFrameRate;
// v.AvgTimePerFrame = iFrameRate;
}
// if overriding the width, set the width
if (iWidth > 0)
{
v.BmiHeader.Width = iWidth;
}
// if overriding the Height, set the Height
if (iHeight > 0)
{
v.BmiHeader.Height = iHeight;
}
// Copy the media structure back
Marshal.StructureToPtr( v, media.formatPtr,false);
// Set the new format
hr = videoStreamConfig.SetFormat( media );
DsError.ThrowExceptionForHR( hr );
DsUtils.FreeAMMediaType(media);
media = null;
// Fix upsidedown video
if (videoControl != null)
{
VideoControlFlags pCapsFlags;
IPin pPin = DsFindPin.ByCategory(capFilter, PinCategory.Capture,0);
hr = videoControl.GetCaps(pPin, out pCapsFlags);
// DsError.ThrowExceptionForHR( hr );
if ((pCapsFlags & VideoControlFlags.FlipVertical) > 0)
{
hr = videoControl.GetMode(pPin, out pCapsFlags);
DsError.ThrowExceptionForHR(hr);
hr = videoControl.SetMode(pPin, 0);
}
}
}
finally
{
Marshal.ReleaseComObject(videoStreamConfig);
}
}
/// <summary> Shut down capture </summary>
private void CloseInterfaces()
{
int hr;
try
{
if( m_mediaCtrl != null )
{
// Stop the graph
hr = m_mediaCtrl.Stop();
m_mediaCtrl = null;
m_bRunning = false;
}
}
catch (Exception ex)
{
Debug.WriteLine(ex);
}
#if DEBUG
if (m_rot != null)
{
m_rot.Dispose();
}
#endif
if (m_FilterGraph != null)
{
Marshal.ReleaseComObject(m_FilterGraph);
m_FilterGraph = null;
}
GC.Collect();
}
/// <summary> sample callback, NOT USED. </summary>
int ISampleGrabberCB.SampleCB(double SampleTime, IMediaSample pSample)
{
Marshal.ReleaseComObject(pSample);
return 0;
}
/// <summary> buffer callback, COULD BE FROM FOREIGN THREAD. </summary>
int ISampleGrabberCB.BufferCB( double SampleTime, IntPtr pBuffer, int BufferLen )
{
// Avoid the possibility that someone is calling SetLogo() at this instant
lock (this)
{
if (m_bmdLogo != null)
{
IntPtr ipSource = m_bmdLogo.Scan0;
IntPtr ipDest = pBuffer;
for (int x=0; x <m_bmdLogo.Height; x++)
{
CopyMemory(ipDest, ipSource, (uint)m_bmdLogo.Stride);
//.RotateFlip(RotateFlipType.RotateNoneFlipY);
ipDest = ((IntPtr)(ipDest.ToInt32() + m_stride));
ipSource = (IntPtr)(ipSource.ToInt32() + m_bmdLogo.Stride);
}
}
}
return 0;
}
}
}
|
|
|
|
|
Thanks for your sharing!! This help me a lot!!
|
|
|
|
|