如何用C#将显示器的图像变为镜像显示呢?就是好像是在镜子里看一样。如果这个实现不了,那么如何使C#编写的整个窗体是镜像显示的呢?就是别的都正常,就C#窗体是镜像的(包括窗体中打开的任何文字、图片等都是镜像的)
最好能实现第一个要求,我想将C#软件做成自动运行的,进入系统后整个显示器变为镜像显示了。
搞了好几天,不知道怎么弄,相关资料也很少,希望高手能给个源码,分不够再加100分呵呵~~~~~~~ ^_^
最好能实现第一个要求,我想将C#软件做成自动运行的,进入系统后整个显示器变为镜像显示了。
搞了好几天,不知道怎么弄,相关资料也很少,希望高手能给个源码,分不够再加100分呵呵~~~~~~~ ^_^
http://msdn.microsoft.com/en-us/library/ms812499.aspx
花钱吃喝没问题,想要更新设备难的很啊!我们的提词器还是98年买的呢!
我这几天也是蛋疼闲着没事在改造提词器呢呵呵
我今天下午将一个CRT显示器的偏转线圈调换了一下,效果很好,但是我想用LCD显示器,很难啊,看来想用程序实现的难度很大,估计要涉及到显卡底层的很多东西,不懂,唉楼上还说用两块镜子二次反射,这也不可行,因为镜子后面有摄像机,而且反射次数越多相当于画面距离主持人越远,效果要打折扣;还有提词器的架子是固定的,和摄像机三脚架是一体的,无法进行二次反射。
你理解错了,不是倒过来,是把CRT的偏转线圈横向扫描翻转,这样图像就变成镜像了。比如说吧,你现在的显示器是正常的,你拿块镜子放到你的显示器前看看文字,发现所有的图像都是翻转的。
但是如果你把显示器图像改为镜像的,你再到镜子里看图像,就变成正常的了。大头贴和提词器都是这个道理。
这个我做过试验,拆出来后显示器背光和线路不容易走,而且效果很差,尤其是经过玻璃二次反射后更差。只能改LCD的成像驱动电路。
不水平翻转显示器,仅翻转该winform程序,如何做呢?
比如在窗体上加一个按钮,点击一下使该程序的所有窗体变为水平翻转状态的镜像显示,再点击一下恢复正常?
类似这样.
Source可以被遮挡,但不能最小化或隐藏(不然就是一片黑),Mirror可以最大化放到全屏.
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.Drawing;class SourceForm:Form
{
public SourceForm()
{
var text = new TextBox();
text.Multiline = true;
text.Dock = DockStyle.Fill;
text.Font = new Font("宋体",20);
Text = "Source";
Timer t = new Timer();
t.Interval = 100;
t.Enabled = true;
var i = 0;
t.Tick += (s, e) =>
{
text.Text = (i++).ToString();
};
Controls.Add(text);
}}class DestForm:Form
{
[DllImport("user32.dll")]
static extern IntPtr GetDC(IntPtr wnd);
[DllImport("user32.dll")]
static extern bool ReleaseDC(IntPtr wnd,IntPtr hdc); [DllImport("gdi32.dll")]
static extern bool StretchBlt(IntPtr hdcDest, int nXOriginDest, int nYOriginDest,
int nWidthDest, int nHeightDest,
IntPtr hdcSrc, int nXOriginSrc, int nYOriginSrc, int nWidthSrc, int nHeightSrc,
uint dwRop); const uint SRCCOPY = 0x00CC0020; public DestForm()
{
Text = "Mirror";
Timer t = new Timer();
BackgroundImageLayout = ImageLayout.Zoom;
t.Interval = 100;
t.Enabled = true;
t.Tick += (s, e) =>CapSrcFormAndMirror();
} void CapSrcFormAndMirror()
{
Bitmap bmp = new Bitmap(program.SrcForm.Size.Width, program.SrcForm.Height);
using (var g = CreateGraphics())
{
var srcDc = GetDC(program.SrcForm.Handle);
var dstDc = g.GetHdc();
StretchBlt(dstDc, 0, 0, bmp.Width, bmp.Height, srcDc, bmp.Width - 1, 0, -bmp.Width , bmp.Height, SRCCOPY);
g.ReleaseHdc();
ReleaseDC(program.SrcForm.Handle, srcDc);
}
}
}class program
{
public static SourceForm SrcForm
{
get;
private set;
}
static void Main()
{
SrcForm = new SourceForm();
SrcForm.Show();
Application.Run(new DestForm());
}
}Mirror.cs
您的这段代码也无法完成我的需求
现在要求简单点:如何使窗体中的RichTextBox控件中的所有文字变成反的呢?
点击一下按钮文字变成反的,再点击一下变成正常的,而且文字的翻转不影响文字的格式?
要实现按一下反转再按一下正常也简单.
看到StretchBlt里传的负值了吗?
弄个状态变量控制一下传值是否反转就行了.
至于文字格式...因为是截图,所以你原本是什么格式它就是什么格式.
除了源窗体不能最小化或隐藏外,我觉得完全可以满足你的需求.
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.Drawing;
class SourceForm:Form
{
RichTextBox txtBox;
public Control SourceControl{
get{return txtBox;}
}
public SourceForm()
{
txtBox = new RichTextBox();
txtBox.Dock = DockStyle.Fill;
Text = "Source";
Controls.Add (txtBox);
}
}
class DestForm:Form
{
[DllImport("user32.dll")]
static extern IntPtr GetDC(IntPtr wnd);
[DllImport("user32.dll")]
static extern bool ReleaseDC(IntPtr wnd,IntPtr hdc); [DllImport("gdi32.dll")]
static extern bool StretchBlt(IntPtr hdcDest, int nXOriginDest, int nYOriginDest,
int nWidthDest, int nHeightDest,
IntPtr hdcSrc, int nXOriginSrc, int nYOriginSrc, int nWidthSrc, int nHeightSrc,
uint dwRop); const uint SRCCOPY = 0x00CC0020;
Panel panel;
Timer timer;
void SetDock (Control ctrl){
ctrl.Height = Height - 60;
ctrl.Width = Width;
ctrl.Anchor = AnchorStyles.Top|AnchorStyles.Bottom|AnchorStyles.Left|AnchorStyles.Right;
}
SourceForm srcForm;
public DestForm(SourceForm srcForm)
{
this.srcForm = srcForm;
srcForm.Show ();
timer = new Timer();
panel = new Panel ();
var checkBox = new CheckBox(); Text = "Mirror";
checkBox.Checked = false;
checkBox.Text = "Mirror On/Off";
checkBox.Dock = DockStyle.Bottom;
checkBox.CheckedChanged += (s,e)=>MirrorState = checkBox.Checked;
SetDock (panel); Controls.Add (panel);
Controls.Add (checkBox);
timer.Interval =1;
timer.Enabled = true;
timer.Tick += (s, e) =>CapSrcFormAndMirror();
} bool MirrorState {
get;
set;
} void CapSrcFormAndMirror()
{
Bitmap bmp = new Bitmap(srcForm.SourceControl.Width, srcForm.SourceControl.Height);
using (var g = panel.CreateGraphics())
{
var srcDc = GetDC(srcForm.SourceControl.Handle);
var dstDc = g.GetHdc();
if (MirrorState)
StretchBlt(dstDc, 0, 0, bmp.Width, bmp.Height, srcDc, bmp.Width - 1, 0, -bmp.Width , bmp.Height, SRCCOPY);
else
StretchBlt(dstDc, 0, 0, bmp.Width, bmp.Height, srcDc, 0, 0, bmp.Width , bmp.Height, SRCCOPY);
g.ReleaseHdc();
ReleaseDC(srcForm.SourceControl.Handle, srcDc);
}
}
}class program
{
static void Main()
{
Application.Run(new DestForm(new SourceForm()));
}
}
稍微改了一下.
换用RichTextBox,你可以在写字板里排好格式粘贴进去.
加了个checkbox控制镜像反转
如果嫌SourceWindow很烦,可以把它弄到需要的大小后移出屏幕.
只要不是最小化或隐藏,放在哪儿都没有问题.
软件默认全屏,点击定义的按键RTB文字滚动以使播音员播音,然后再次点击定义的按键滚动字幕停止。
我用截图的方法虽然能做到,但是计时器每2msTick一次内存迅速增加,不一会儿就占用1G以上内存,因此该方法只能实现镜像截图而无法实际应用到软件中。所以我认为,最好的方法就是直接使RTB中的文字变成镜像的,这个我不清楚如何做,其实如果有个镜像字体一下就搞定了,什么都不用做了,只要点击镜像按钮在事件中用镜像字体格式化一下RTB就OK了。
或者如何使RTB中的文字直接变成反的呢?我见过很多大头贴软件,它们的文字就是反的,可以直接编辑复制粘贴打字等操作的,不知道是如何做的?能提供如黑体等标准镜像字体的,给分400分呵呵
内存占用大肯定是有内存泄露了.最好仔细检查你的代码.(比如我上面那两段,都有一个很严重的内存泄露,估计是刚开始用GDI+做的改StretchBlt的时候疏忽了)
http://topic.csdn.net/u/20110513/11/dad59784-9d00-4a36-8ea2-aac5333e2c5d.html
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.Drawing;class SourceForm:Form
{
RichTextBox txtBox;
public Control SourceControl{
get{return txtBox;}
}
public DestForm DestForm{
get;
set;
}
public SourceForm()
{
txtBox = new RichTextBox();
txtBox.Dock = DockStyle.Fill;
this.FullScreen();
Left = 0;
FormBorderStyle = FormBorderStyle.None;
txtBox.KeyUp += (s,e)=>{
switch (e.KeyCode)
{
case Keys.Escape:
DestForm.Close();
break;
case Keys.F4:
DestForm.MirrorState = !DestForm.MirrorState ;
Left = DestForm.MirrorState?4000:0;
break;
}
};
Text = "Source";
Controls.Add (txtBox);
}
}
class DestForm:Form
{
[DllImport("user32.dll")]
static extern IntPtr GetDC(IntPtr wnd);
[DllImport("user32.dll")]
static extern bool ReleaseDC(IntPtr wnd,IntPtr hdc); [DllImport("gdi32.dll")]
static extern bool StretchBlt(IntPtr hdcDest, int nXOriginDest, int nYOriginDest,
int nWidthDest, int nHeightDest,
IntPtr hdcSrc, int nXOriginSrc, int nYOriginSrc, int nWidthSrc, int nHeightSrc,
uint dwRop); const uint SRCCOPY = 0x00CC0020;
Timer timer;
void SetDock (Control ctrl){
ctrl.Height = Height - 60;
ctrl.Width = Width;
ctrl.Anchor = AnchorStyles.Top|AnchorStyles.Bottom|AnchorStyles.Left|AnchorStyles.Right;
}
SourceForm srcForm;
public DestForm(SourceForm srcForm)
{
this.srcForm = srcForm;
srcForm.DestForm = this;
srcForm.Show ();
this.FullScreen();
TopMost = false;
timer = new Timer(); Text = "Mirror";
GotFocus += (s,e)=> srcForm.SourceControl.Focus();
timer.Interval =1;
timer.Enabled = true;
timer.Tick += (s, e) =>CapSrcFormAndMirror();
}
public bool MirrorState {
get;
set;
} void CapSrcFormAndMirror()
{
var width = srcForm.SourceControl.Width;
var height = srcForm.SourceControl.Height;
srcForm.SourceControl.Invalidate ();
using (var g = CreateGraphics())
{
var srcDc = GetDC(srcForm.SourceControl.Handle);
var dstDc = g.GetHdc();
if (MirrorState)
StretchBlt(dstDc, 0, 0, width , height, srcDc, width - 1, 0, -width , height, SRCCOPY);
else
StretchBlt(dstDc, 0, 0, width, height, srcDc, 0, 0, width , height, SRCCOPY);
g.ReleaseHdc();
ReleaseDC(srcForm.SourceControl.Handle, srcDc);
}
}
}static class program
{
public static void FullScreen (this Form frm){
frm.StartPosition = FormStartPosition.Manual;
frm.FormBorderStyle = FormBorderStyle.None;
frm.Size = Screen.PrimaryScreen.Bounds .Size;
frm.Location = new Point (0,0);
}
static void Main()
{
Application.Run(new DestForm(new SourceForm()));
}
}
按照你的要求又改了一下.
仍然是截图;运行初始无镜像全屏,F4切换镜像,可以输
入文字,Esc退出(不要按Alt+F4否则会崩溃),修正了内
存泄露我连续跑了30多分钟内存耗用稳定在17M左右缺点在于反转模式下鼠标点击无效(其实就是把源窗体
移到了屏幕外).我没有设字体,如果需要rtf格式化过的文
本的话可以用写字板编辑后粘贴进去.至于需要滚动啥的
你自己加了
分辨率考虑了的,我是用Screen取的主显示器的分辨率.
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;namespace 显示器镜像
{
public partial class Form1 : Form
{ public Control SourceControl
{
get
{
return richTextBox1;
}
}
public DestForm DestForm
{
get;
set;
}
public Form1()
{
this.FullScreen();
FormBorderStyle = FormBorderStyle.None;
InitializeComponent();
} private void richTextBox1_KeyDown(object sender, KeyEventArgs e)
{
switch (e.KeyCode)
{
case Keys.Escape:
DestForm.Close();
break;
case Keys.F4:
DestForm.MirrorState = !DestForm.MirrorState ;
//Left = DestForm.MirrorState?600:0;
Left = DestForm.MirrorState ? 0 : Screen.PrimaryScreen.WorkingArea.Width;
break;
}
}
}
public class DestForm : Form
{
[DllImport("user32.dll")]
static extern IntPtr GetDC(IntPtr wnd);
[DllImport("user32.dll")]
static extern bool ReleaseDC(IntPtr wnd, IntPtr hdc); [DllImport("gdi32.dll")]
static extern bool StretchBlt(IntPtr hdcDest, int nXOriginDest, int nYOriginDest,
int nWidthDest, int nHeightDest,
IntPtr hdcSrc, int nXOriginSrc, int nYOriginSrc, int nWidthSrc, int nHeightSrc,
uint dwRop); const uint SRCCOPY = 0x00CC0020; Timer timer; Form1 srcForm;
public DestForm(Form1 srcForm)
{
Label lb1=new Label();
lb1.Text="镜像窗体";
this.Controls.Add(lb1);
this.srcForm = srcForm;
srcForm.DestForm = this;
srcForm.Show();
this.FullScreen();
TopMost = false;
timer = new Timer(); Text = "Mirror"; GotFocus += (s, e) => srcForm.SourceControl.Focus(); timer.Interval = 1;
timer.Enabled = true;
timer.Tick += (s, e) => CapSrcFormAndMirror(); } public bool MirrorState
{
get;
set;
} void CapSrcFormAndMirror()
{
var width = srcForm.SourceControl.Width;
var height = srcForm.SourceControl.Height;
srcForm.SourceControl.Invalidate();
using (var g = CreateGraphics())
{
var srcDc = GetDC(srcForm.SourceControl.Handle);
var dstDc = g.GetHdc(); if (MirrorState)
StretchBlt(dstDc, 0, 0, width, height, srcDc, width - 1, 0, -width, height, SRCCOPY);
else
StretchBlt(dstDc, 0, 0, width, height, srcDc, 0, 0, width, height, SRCCOPY); g.ReleaseHdc();
ReleaseDC(srcForm.SourceControl.Handle, srcDc);
}
}
} public static class Program
{ public static void FullScreen(this Form frm)
{
frm.StartPosition = FormStartPosition.Manual;
frm.FormBorderStyle = FormBorderStyle.None;
frm.Size = Screen.PrimaryScreen.Bounds.Size;
frm.Location = new Point(0, 0);
}
/// <summary>
/// 应用程序的主入口点。
/// </summary>
[STAThread] static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
// Application.Run(new Form1());
Application.Run(new DestForm(new Form1())); }
}}
你的代码越来越有意思了,看来分数要给你了
我的测试步骤:
1,新建项目,在窗体上拖一个RTB控件,Dock属性Fill;
2,参考你的代码,修改。同时为了区别镜像窗体,我在镜像窗体上放了一个Label标签
3,F5运行,结果:RTB不能全屏,按F4只能看到镜像窗体的标签,镜像窗体的RTB不能显示,如果修改 case Keys.F4:
DestForm.MirrorState = !DestForm.MirrorState ;
//Left = DestForm.MirrorState?600:0;
Left = DestForm.MirrorState ? 0 : Screen.PrimaryScreen.WorkingArea.Width;
这里代码可以让镜像窗体的RTB显示,但是我控制不好,不熟悉GDI,希望你能指点一下
嘿嘿,新WPF 里面 + 效果就OK 啦