none
用内存中的图片,做鼠标cursor RRS feed

答案

  • OK, 明了。WPF实现鼠标指针必须是.cur文件或者通过流来读取图片。你所谓的不能用流,其实是不能用文件流,对于你的需求我们可以通过 API 来实现.
    你看下我的实现:
      private struct IconInfo
      {
       public bool fIcon;
       public int xHotspot;
       public int yHotspot;
       public IntPtr hbmMask;
       public IntPtr hbmColor;
      }
    
      [DllImport("user32.dll")]
      private static extern IntPtr CreateIconIndirect(ref IconInfo icon);
    
      [DllImport("user32.dll")]
      [return: MarshalAs(UnmanagedType.Bool)]
      private static extern bool GetIconInfo(IntPtr hIcon, ref IconInfo pIconInfo);
    
      private static Cursor InternalCreateCursor(
       System.Drawing.Bitmap bmp,
       int xHotSpot, 
       int yHotSpot)
      {
       IconInfo tmp = new IconInfo();
       GetIconInfo(bmp.GetHicon(), ref tmp);
       tmp.xHotspot = xHotSpot;
       tmp.yHotspot = yHotSpot;
       tmp.fIcon = false;
    
       IntPtr ptr = CreateIconIndirect(ref tmp);
       SafeFileHandle handle = new SafeFileHandle(ptr, true);
       return CursorInteropHelper.Create(handle);
      }
    
    
      public MainWindow()
      {
       InitializeComponent();
    
       BitmapImage b = new BitmapImage(new Uri(@"...", UriKind.Absolute));
    
       int[] r = { 10, 10, 32, 32 };
       BitmapSource curBitmap = cutImage(b, r);
    
       int width = (int)curBitmap.Width;
       int height = (int)curBitmap.Height;
    
       int[] pixels = new int[width * height];
       int stride = width * curBitmap.PixelWidth / 8;
       curBitmap.CopyPixels(pixels, stride, 0);
       System.Drawing.Bitmap bitmap = new System.Drawing.Bitmap(width, height, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
       for (int y = 0; y < height; y++)
        for (int x = 0; x < width; x++)
         bitmap.SetPixel(x, y, System.Drawing.Color.FromArgb(pixels[y * width + x]));
    
       Cursor cur = InternalCreateCursor(bitmap, 5, 5);
       this.Cursor = cur;
       bitmap.Dispose();
      }
    
      /// 截取图片
      public BitmapSource cutImage(BitmapSource bs, int[] r)
      {
       return new CroppedBitmap(
         BitmapFrame.Create(bs),
         new Int32Rect(r[0], r[1], r[2], r[3]));
      }
    


    Sincerely,
     
    Bob Bao [MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    • 已标记为答案 黑心 2011年5月30日 8:38
    2011年5月30日 7:02
    版主

全部回复

  • 如何去理解你所说的内存中的图片, 是指剪切版中的还是一个图片对象,还是一段字节数组所代表的图像? 我没有理解你的内存中的图片的含义。 能否解释下?谢谢。

    Sincerely,


    Bob Bao [MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    2011年5月27日 6:40
    版主
  • 是正常的图片,用url加载到内存里,成为1个图片对象,然后裁切成小的图
    2011年5月27日 8:00
  • 还是太笼统了,有没有什么具体的已有的实现代码,具体是什么样的格式,你怎么写的Url

    因为鼠标Cur是可以封装Image的,但要看情况了,看是什么样的Image


    Bob Bao [MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.


    2011年5月27日 10:48
    版主
  •             Image Spirit = new Image();
                BitmapImage b = new BitmapImage(new Uri(s, UriKind.Absolute));
                Spirit.Source = b;

     

    /// 截取图片
            public BitmapSource cutImage(BitmapSource bs, int[] r)
            {
                return new CroppedBitmap(

                    BitmapFrame.Create(bs),

                    new Int32Rect(r[0], r[1], r[2], r[3])

                     );
            }

    2011年5月30日 3:52
  • OK, 明了。WPF实现鼠标指针必须是.cur文件或者通过流来读取图片。你所谓的不能用流,其实是不能用文件流,对于你的需求我们可以通过 API 来实现.
    你看下我的实现:
      private struct IconInfo
      {
       public bool fIcon;
       public int xHotspot;
       public int yHotspot;
       public IntPtr hbmMask;
       public IntPtr hbmColor;
      }
    
      [DllImport("user32.dll")]
      private static extern IntPtr CreateIconIndirect(ref IconInfo icon);
    
      [DllImport("user32.dll")]
      [return: MarshalAs(UnmanagedType.Bool)]
      private static extern bool GetIconInfo(IntPtr hIcon, ref IconInfo pIconInfo);
    
      private static Cursor InternalCreateCursor(
       System.Drawing.Bitmap bmp,
       int xHotSpot, 
       int yHotSpot)
      {
       IconInfo tmp = new IconInfo();
       GetIconInfo(bmp.GetHicon(), ref tmp);
       tmp.xHotspot = xHotSpot;
       tmp.yHotspot = yHotSpot;
       tmp.fIcon = false;
    
       IntPtr ptr = CreateIconIndirect(ref tmp);
       SafeFileHandle handle = new SafeFileHandle(ptr, true);
       return CursorInteropHelper.Create(handle);
      }
    
    
      public MainWindow()
      {
       InitializeComponent();
    
       BitmapImage b = new BitmapImage(new Uri(@"...", UriKind.Absolute));
    
       int[] r = { 10, 10, 32, 32 };
       BitmapSource curBitmap = cutImage(b, r);
    
       int width = (int)curBitmap.Width;
       int height = (int)curBitmap.Height;
    
       int[] pixels = new int[width * height];
       int stride = width * curBitmap.PixelWidth / 8;
       curBitmap.CopyPixels(pixels, stride, 0);
       System.Drawing.Bitmap bitmap = new System.Drawing.Bitmap(width, height, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
       for (int y = 0; y < height; y++)
        for (int x = 0; x < width; x++)
         bitmap.SetPixel(x, y, System.Drawing.Color.FromArgb(pixels[y * width + x]));
    
       Cursor cur = InternalCreateCursor(bitmap, 5, 5);
       this.Cursor = cur;
       bitmap.Dispose();
      }
    
      /// 截取图片
      public BitmapSource cutImage(BitmapSource bs, int[] r)
      {
       return new CroppedBitmap(
         BitmapFrame.Create(bs),
         new Int32Rect(r[0], r[1], r[2], r[3]));
      }
    


    Sincerely,
     
    Bob Bao [MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    • 已标记为答案 黑心 2011年5月30日 8:38
    2011年5月30日 7:02
    版主
  • System.Drawing.Bitmap

    WPF中,找不到程序集引用

    2011年5月30日 8:02
  • Winform的程序集,你要手动添加以下。
    Bob Bao [MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    2011年5月30日 8:11
    版主
  • 不行,生成的 cursor 只是一团模糊

    2011年5月30日 9:08
  • 请确保你裁剪完之后的图片不是模糊的,API只是原封不动把图像的像素封装成Cursor,不会改变图像的。
    Bob Bao [MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    2011年5月30日 9:18
    版主
  • png图片,切成16*16大小的,不模糊,生成的是模糊影子
    2011年5月30日 9:31
  • 把你测试项目传到  www.skydrive.com  去,分享给我看看吧!或者直接发我邮箱 v-bobbao (at) microsoft.com
    Bob Bao [MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    2011年5月30日 9:41
    版主
  • OK, 是因为你用来测试的图片的Format不是 32位 ARGB 类型的,而是 Indexed8BPP的,所以上面的代码没有正确的转换BitmapSoruce到Bitmap对象。

    解决方法,你要把你的图片现转成32位色之后再使用上面的代码。


    Bob Bao [MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    2011年5月30日 10:07
    版主
  • 对了,我晚上想到,你还是依据那片文章来实现,通过一个encoder来把你的裁剪的图像转成Bitmap对象: http://www.switchonthecode.com/tutorials/wpf-tutorial-how-to-use-custom-cursors  这样图像内容格式可以灵活一点。
    Bob Bao [MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    2011年5月30日 16:46
    版主