Taking screenshot of a device screen using c# - compact-framework

Hii...
Is there any way to take screenshot of the application running on WIN CE5.0 device screen.
Thanxxx in advance....

using System;
using System.Collections.Generic;
using System.IO;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using System.Drawing;
using System.Drawing.Imaging;
namespace ScreenShot
{
public class Program
{
enum RasterOperation : uint { SRC_COPY = 0x00CC0020 }
[DllImport("coredll.dll")]
static extern int BitBlt(IntPtr hdcDest, int nXDest, int nYDest, int nWidth, int nHeight, IntPtr hdcSrc, int nXSrc, int nYSrc, RasterOperation rasterOperation);
[DllImport("coredll.dll")]
private static extern IntPtr GetDC(IntPtr hwnd);
[DllImport("coredll.dll")]
private static extern int ReleaseDC(IntPtr hwnd, IntPtr hdc);
static void Main(String[] args)
{
Rectangle bounds = Screen.PrimaryScreen.Bounds;
IntPtr hdc = GetDC(IntPtr.Zero);
Bitmap bitmap = new Bitmap(bounds.Width, bounds.Height, PixelFormat.Format16bppRgb565);
using (Graphics graphics = Graphics.FromImage(bitmap))
{
IntPtr dstHdc = graphics.GetHdc();
BitBlt(dstHdc, 0, 0, bounds.Width, bounds.Height, hdc, 0, 0,
RasterOperation.SRC_COPY);
graphics.ReleaseHdc(dstHdc);
}
bitmap.Save("screenshot.jpg", ImageFormat.Jpeg);
ReleaseDC(IntPtr.Zero, hdc);
}
}
}

Use OpenNetCF SDF
http://blog.opennetcf.com/ctacke/2009/03/11/ScreenCaptureInTheCompactFramework.aspx
// create a bitmap and graphics objects for the capture
Drawing.Bitmap destinationBmp = new Drawing.Bitmap(Forms.Screen.PrimaryScreen.Bounds.Width, Forms.Screen.PrimaryScreen.Bounds.Height);
Drawing.Graphics g = Drawing.Graphics.FromImage(destinationBmp);
GraphicsEx gx = GraphicsEx.FromGraphics(g);
// capture the current screen
gx.CopyFromScreen(0, 0, 0, 0, Forms.Screen.PrimaryScreen.Bounds.Size, CopyPixelOperation.SourceCopy);
// save the file
destinationBmp.Save(filename, System.Drawing.Imaging.ImageFormat.Png);
// clean house
gx.Dispose();
g.Dispose();
destinationBmp.Dispose();

Related

C#: Error calling the camera on the tablet of Microsoft Surface-win10

[DllImport("avicap32.dll")]
public static extern bool capGetDriverDescriptionA(short wDriver, byte[] lpszName, int cbName, byte[] lpszVer, int cbVer);
[DllImport("avicap32.dll")]
public static extern IntPtr capCreateCaptureWindowA(byte[] lpszWindowName, int dwStyle, int x, int y, int nWidth, int nHeight, IntPtr hWndParent, int nID);
[DllImport("User32.dll")]
public static extern bool SendMessage(IntPtr hWnd, int wMsg, short wParam, int lParam);
[DllImport("User32.dll")]
public static extern bool SendMessage(IntPtr hWnd, int wMsg, bool wParam, int lParam);
public const int WM_USER = 0x400;
public const int WS_CHILD = 0x40000000;
public const int WS_VISIBLE = 0x10000000;
public const int WM_CAP_DRIVER_CONNECT = WM_USER + 10;
public const int WM_CAP_DRIVER_DISCONNECT = WM_USER + 11;
public const int WM_CAP_SET_PREVIEW = WM_USER + 50;
public const int WM_CAP_SET_PREVIEWRATE = WM_USER + 52;
byte[] lpszName = new byte[100];
byte[] lpszVer = new byte[100];
capGetDriverDescriptionA(0, lpszName, 100, lpszVer, 100);
IntPtr lwndC = capCreateCaptureWindowA(lpszName, WS_VISIBLE + WS_CHILD, 0, 0, mWidth, mHeight, mControlPtr, 0);
//When the program runs to the following code, a camera selection dialog box (Microsoft Camera Front/Microsoft Camera Rear) appears. After selecting any of them, the code in the if statement is not executed,and the camera cannot run normally. Can anyone help me? Why is this happening, thank you.
if (SendMessage(lwndC, VideoAPI.WM_CAP_DRIVER_CONNECT, 0, 0))
{
SendMessage(lwndC, WM_CAP_SET_PREVIEWRATE, 66, 0);
SendMessage(lwndC, WM_CAP_SET_PREVIEW, true, 0);
}

NAudio - ASIO Playback to device (static only)

I'm trying to route ASIO audio to my playback devices, however, all I hear is static.
ASIO Setup
BIT_PER_SAMPLE = 24
SAMPLE_RATE = 48000
Currently, trying with 1 channel into 1 playback device called "Line 1" for testing. The playback of the sound is static.
EDIT: The code below has been updated. It will take 64 channels of ASIO input and route them one at a time into Waveout devices (I'm using Virtual Audio Cable to create them)
private static AsioOut asioOut;
private static AsioInputPatcher inputPatcher;
private static readonly int BIT_PER_SAMPLE = 16;
private static readonly int SAMPLE_RATE = 48000;
private static readonly int NUMBER_OF_CHANNELS = 64;
private static BufferedWaveProvider[] bufferedWaveProviders = new BufferedWaveProvider[NUMBER_OF_CHANNELS];
private static WaveOut[] waveouts = new WaveOut[NUMBER_OF_CHANNELS];
[STAThread]
static void Main(string[] args)
{
InitDevices();
Record();
while (true)
{
Console.WriteLine("Recording...press any key to Exit.");
Console.ReadKey(true);
break;
}
asioOut.Stop();
asioOut.Dispose();
asioOut = null;
}
private static void Record()
{
inputPatcher = new AsioInputPatcher(SAMPLE_RATE, NUMBER_OF_CHANNELS, NUMBER_OF_CHANNELS);
asioOut = new AsioOut(AsioOut.GetDriverNames()[0]);
asioOut.InitRecordAndPlayback(new SampleToWaveProvider(inputPatcher),
NUMBER_OF_CHANNELS, 0);
asioOut.AudioAvailable += OnAsioOutAudioAvailable;
asioOut.Play();
}
private static void InitDevices()
{
for (int n = -1; n < WaveOut.DeviceCount; n++)
{
WaveOutCapabilities caps = WaveOut.GetCapabilities(n);
if (caps.ProductName.StartsWith("Line"))
{
int _number = int.Parse(caps.ProductName.Split(' ')[1]);
if (_number <= NUMBER_OF_CHANNELS)
{
waveouts[_number - 1] = new WaveOut() { DeviceNumber = n };
bufferedWaveProviders[_number - 1] = new BufferedWaveProvider(new WaveFormat(SAMPLE_RATE, BIT_PER_SAMPLE, 2));
waveouts[_number - 1].Init(bufferedWaveProviders[_number - 1]);
waveouts[_number - 1].Play();
}
}
}
}
static void OnAsioOutAudioAvailable(object sender, AsioAudioAvailableEventArgs e)
{
inputPatcher.ProcessBuffer(e.InputBuffers, e.OutputBuffers,
e.SamplesPerBuffer, e.AsioSampleType);
for (int outputChannel = 0; outputChannel < e.OutputBuffers.Length; outputChannel++)
{
byte[] buf = new byte[e.SamplesPerBuffer * (BIT_PER_SAMPLE / 8)];
Marshal.Copy(e.OutputBuffers[outputChannel], buf, 0, e.SamplesPerBuffer * (BIT_PER_SAMPLE / 8));
bufferedWaveProviders[outputChannel].AddSamples(buf, 0, buf.Length);
}
e.WrittenToOutputBuffers = true;
}
There are two main problems with your code. First, InputBuffers is one per channel, not sample. Second, when you set e.WrittenToOutputBuffers = true you are saying that you have written to e.OutputBuffers which you haven't. So they will just contain uninitialized data.
If you want to see an example of low-level manipulation of ASIO buffers, then check out my ASIO patch bay sample project.

Slow image processing of images from filesystem as compared to the webcam

I was able to follow the csharp-sample-apps from the github repo for Affectiva. I ran the demo using my webcam and the processing and performance was great.I am not getting the same processing speed from the PhotoDetector when I try to run it over images in filesystem. Any help or improvement would be appreciated.
namespace Logical.EmocaoFace
{
public class AnaliseEmocao : Affdex.ImageListener, Affdex.ProcessStatusListener
{
private Bitmap img { get; set; }
private Dictionary<int, Affdex.Face> faces { get; set; }
private Affdex.Detector detector { get; set; }
private ReaderWriterLock rwLock { get; set; }
public void processaEmocaoImagem()
{
for (int i = 0; i < resultado.count; i++){
RetornaEmocaoFace();
if (faceAffdex != null)
{
}
}
}
public void RetornaEmocaoFace(string caminhoImagem)
{
Affdex.Detector detector = new Affdex.PhotoDetector(1, Affdex.FaceDetectorMode.LARGE_FACES);
detector.setImageListener(this);
detector.setProcessStatusListener(this);
if (detector != null)
{
//ProcessVideo videoForm = new ProcessVideo(detector);
detector.setClassifierPath(#"D:\Desenvolvimento\Componentes\Afectiva\data");
detector.setDetectAllEmotions(true);
detector.setDetectAllExpressions(false);
detector.setDetectAllEmojis(false);
detector.setDetectAllAppearances(false);
detector.start();
((Affdex.PhotoDetector)detector).process(LoadFrameFromFile(caminhoImagem));
detector.stop();
}
}
static Affdex.Frame LoadFrameFromFile(string fileName)
{
Bitmap bitmap = new Bitmap(fileName);
// Lock the bitmap's bits.
Rectangle rect = new Rectangle(0, 0, bitmap.Width, bitmap.Height);
BitmapData bmpData = bitmap.LockBits(rect, ImageLockMode.ReadWrite, bitmap.PixelFormat);
// Get the address of the first line.
IntPtr ptr = bmpData.Scan0;
// Declare an array to hold the bytes of the bitmap.
int numBytes = bitmap.Width * bitmap.Height * 3;
byte[] rgbValues = new byte[numBytes];
int data_x = 0;
int ptr_x = 0;
int row_bytes = bitmap.Width * 3;
// The bitmap requires bitmap data to be byte aligned.
// http://stackoverflow.com/questions/20743134/converting-opencv-image-to-gdi-bitmap-doesnt-work-depends-on-image-size
for (int y = 0; y < bitmap.Height; y++)
{
Marshal.Copy(ptr + ptr_x, rgbValues, data_x, row_bytes);//(pixels, data_x, ptr + ptr_x, row_bytes);
data_x += row_bytes;
ptr_x += bmpData.Stride;
}
bitmap.UnlockBits(bmpData);
//Affdex.Frame retorno = new Affdex.Frame(bitmap.Width, bitmap.Height, rgbValues, Affdex.Frame.COLOR_FORMAT.BGR);
//bitmap.Dispose();
//return retorno;
return new Affdex.Frame(bitmap.Width, bitmap.Height, rgbValues, Affdex.Frame.COLOR_FORMAT.BGR);
}
public void onImageCapture(Affdex.Frame frame)
{
frame.Dispose();
}
public void onImageResults(Dictionary<int, Affdex.Face> faces, Affdex.Frame frame)
{
byte[] pixels = frame.getBGRByteArray();
this.img = new Bitmap(frame.getWidth(), frame.getHeight(), PixelFormat.Format24bppRgb);
var bounds = new Rectangle(0, 0, frame.getWidth(), frame.getHeight());
BitmapData bmpData = img.LockBits(bounds, ImageLockMode.WriteOnly, img.PixelFormat);
IntPtr ptr = bmpData.Scan0;
int data_x = 0;
int ptr_x = 0;
int row_bytes = frame.getWidth() * 3;
// The bitmap requires bitmap data to be byte aligned.
// http://stackoverflow.com/questions/20743134/converting-opencv-image-to-gdi-bitmap-doesnt-work-depends-on-image-size
for (int y = 0; y < frame.getHeight(); y++)
{
Marshal.Copy(pixels, data_x, ptr + ptr_x, row_bytes);
data_x += row_bytes;
ptr_x += bmpData.Stride;
}
img.UnlockBits(bmpData);
this.faces = faces;
frame.Dispose();
}
public void onProcessingException(Affdex.AffdexException A_0)
{
throw new NotImplementedException("Encountered an exception while processing " + A_0.ToString());
}
public void onProcessingFinished()
{
string idArquivo = CodEspaco + "," + System.Guid.NewGuid().ToString();
for(int i = 0; i < faces.Count; i++)
{
}
}
}
public static class GraphicsExtensions
{
public static void DrawCircle(this Graphics g, Pen pen,
float centerX, float centerY, float radius)
{
g.DrawEllipse(pen, centerX - radius, centerY - radius,
radius + radius, radius + radius);
}
}
}
Found the answer to my own question:
Using PhotoDetector is not ideal in this case since it is expensive to use the Face Detector configuration on subsequent frame calls.
The best option to improve the performance would be to use an instance of the FrameDetector Class.
Here is a getting started guide to analyze-frames.

WINCODEC_ERR_WIN32ERROR 0x88982F94 when calling IWICComponentFactory.CreateBitmapFromMemory

I'm getting the following error when calling IWICComponentFactory.CreateBitmapFromMemory and passing it a pointer to Scan0 of a 32bppArgb GDI+ bitmap
WINCODEC_ERR_WIN32ERROR
0x88982F94
Windows Codecs received an error from the Win32 system.
IWICComponentFactory interface decl:
new IWICBitmap CreateBitmapFromMemory(
uint uiWidth,
uint uiHeight,
[MarshalAs(UnmanagedType.LPStruct)]
Guid pixelFormat,
uint cbStride,
uint cbBufferSize,
[MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 5)]
byte[] pbBuffer
);
new IWICBitmap CreateBitmapFromMemory(
uint uiWidth,
uint uiHeight,
[MarshalAs(UnmanagedType.LPStruct)]
Guid pixelFormat,
uint cbStride,
uint cbBufferSize,
IntPtr pbBuffer
);
Full code:
public static IWICBitmap ToWic(IWICComponentFactory factory, Bitmap bit) {
BitmapData bd = bit.LockBits(new Rectangle(0, 0, bit.Width, bit.Height),
ImageLockMode.ReadOnly, bit.PixelFormat);
IWICBitmap b = null;
try {
//Create WIC bitmap directly from unmanaged memory
b = factory.CreateBitmapFromMemory((uint)bit.Width, (uint)bit.Height,
ConversionUtils.FromPixelFormat(bit.PixelFormat), (uint)bd.Stride,
(uint)(bd.Stride * bd.Height), bd.Scan0);
return b;
} finally {
bit.UnlockBits(bd);
}
}
Width, Height, buffer size, format GUID, and scan size all seem correct. I can't figure out why this is happening (there are no google results for the error code or message
This isn't an answer as to why the original code doesn't work - but it's a workaround. Using IWICImagingFactory_CreateBitmapFromMemory_Proxy , everything works fine. But why didn't the original work as it's supposed to? And why the _Proxy methods with near-identical signatures?
[DllImport("WindowsCodecs.dll", EntryPoint = "IWICImagingFactory_CreateBitmapFromMemory_Proxy")]
internal static extern int CreateBitmapFromMemory(IWICComponentFactory factory, uint width, uint height, ref Guid pixelFormatGuid, uint stride, uint cbBufferSize, IntPtr pvPixels, out IWICBitmap ppIBitmap);
public static IWICBitmap ToWic(IWICComponentFactory factory, Bitmap bit) {
Guid pixelFormat = ConversionUtils.FromPixelFormat(bit.PixelFormat);
if (pixelFormat == Guid.Empty) throw new NotSupportedException("PixelFormat " + bit.PixelFormat.ToString() + " not supported.");
BitmapData bd = bit.LockBits(new Rectangle(0, 0, bit.Width, bit.Height), ImageLockMode.ReadOnly, bit.PixelFormat);
IWICBitmap b = null;
try {
//Create WIC bitmap directly from unmanaged memory
long result = CreateBitmapFromMemory(factory, (uint)bit.Width,
(uint)bit.Height, ref pixelFormat, (uint)bd.Stride,
(uint)(bd.Stride * bd.Height), bd.Scan0, out b);
if (result == 0x80070057) throw new ArgumentException();
if (result < 0) throw new Exception("HRESULT " + result);
return b;
} finally {
bit.UnlockBits(bd);
}
}
For reference, here is the COM method and here is the proxy method. Both use [IN] BYTE *pbBuffer.

Compact Framework - Keep modal window in front of windows bar after closing CaptureCameraDialog

I am working on a windows mobile application. I have created a wizard that uses a modal window so that the windows bar is hidden. One of the wizard stages has requires a picture to be taken. After launching the CaptureCameraDialog, the windows bar appears and remains even after the CaptureCameraDialog is closed. Is there any way to bring my dialog form back in front of the windows bar?
I eventually managed to find some code on the web that did what I was looking for. Here it is:
public partial class myForm : Form
{
public myForm()
{
InitializeComponent();
this.GotFocus += delegate(object sender, EventArgs args)
{
//var intPtr = FindWindow("CaptureReturnForm", "");
SetForegroundWindow(GetFocus());
bool result = SHFullScreen(GetFocus(), SHFS_HIDESTARTICON |
SHFS_HIDETASKBAR | SHFS_HIDESIPBUTTON); // 0x0020);
};
}
[DllImport("coredll.dll")]
private static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
[DllImport("coredll.dll", EntryPoint = "SetForegroundWindow")]
private static extern int SetForegroundWindow(IntPtr hWnd);
[DllImport("coredll.dll")]
internal static extern IntPtr GetFocus();
[DllImport("aygshell.dll")]
internal static extern bool SHFullScreen(IntPtr hWnd, uint dwState);
const uint SHFS_SHOWTASKBAR = 0x1;
const uint SHFS_HIDETASKBAR = 0x2;
const uint SHFS_SHOWSIPBUTTON = 0x4;
const uint SHFS_HIDESIPBUTTON = 0x8;
const uint SHFS_SHOWSTARTICON = 0x10;
const uint SHFS_HIDESTARTICON = 0x20;
const int HWND_TOPMOST = -1;
const int HWND_NOTOPMOST = -2;
const uint SWP_SHOWWINDOW = 0x40;
const uint SM_CXSCREEN = 0x0;
const uint SM_CYSCREEN = 0x1;
private const int HHTASKBARHEIGHT = 26;
}