如何使用佳能相机lib拍照并在pictureBox中显示拍摄的图像?收到错误

时间:2015-12-12 02:40:34

标签: c# .net winforms

这里有人提出解决方案:

最简单的方法是在下载图像时订阅事件。 要执行此操作,请转到SDKHandler类,区域自定义事件和此事件: 隐藏复制代码 公共事件ImageUpdate ImageReady; 然后在区域Eventhandling,方法Camera_SDKObjectEvent的情况下ObjectEvent_DirItemRequestTransfer,替换这个 隐藏复制代码

DownloadImage(inRef, ImageSaveDirectory);

用这个: 隐藏复制代码

if (ImageReady != null) ImageReady(DownloadImage(inRef));

因此,不是将拍摄的图像下载到高清,而是将其下载到图像中并激活ImageReady事件。

现在,您需要做的就是在使用以下方法初始化MainForm时订阅该事件: 隐藏复制代码

CameraHandler.ImageReady += new SDKHandler.ImageUpdate(SDK_ImageReady);

(只是把它放在其他事件订阅线下) 现在你用这个方法发生了这个事件: 隐藏复制代码

private void SDK_ImageReady(Image img)
{
   LiveViewPicBox.Image = img;
   //you may want to save the image to the hd too. it would work like this:
   //img.Save(@"C:\Path\To\Save\image1.jpg");
}

但我无法通过我遇到错误的第一步。

这就是我在自定义事件区域中所做的:

#region Custom Events

        public delegate void CameraAddedHandler();
        public delegate void ProgressHandler(int Progress);
        public delegate void StreamUpdate(Stream img);
        public delegate void BitmapUpdate(Bitmap bmp);
        public delegate void ImageUpdate(IntPtr objects);

        /// <summary>
        /// Fires if a camera is added
        /// </summary>
        public event CameraAddedHandler CameraAdded;
        /// <summary>
        /// Fires if any process reports progress
        /// </summary>
        public event ProgressHandler ProgressChanged;
        /// <summary>
        /// Fires if the live view image has been updated
        /// </summary>
        public event StreamUpdate LiveViewUpdated;
        /// <summary>
        /// If the camera is disconnected or shuts down, this event is fired
        /// </summary>
        public event EventHandler CameraHasShutdown;
        /// <summary>
        /// If an image is downloaded, this event fires with the downloaded image.
        /// </summary>
        public event BitmapUpdate ImageDownloaded;

        public event ImageUpdate ImageReady;

        #endregion

我添加了一行:

public delegate void ImageUpdate(IntPtr objects);
public event ImageUpdate ImageReady;

然后我改变了切换线,就像他在SDKObjectEvent中的解决方案中说的那样:

private uint Camera_SDKObjectEvent(uint inEvent, IntPtr inRef, IntPtr inContext)
        {
            //handle object event here
            switch (inEvent)
            {
                case EDSDK.ObjectEvent_All:
                    break;
                case EDSDK.ObjectEvent_DirItemCancelTransferDT:
                    break;
                case EDSDK.ObjectEvent_DirItemContentChanged:
                    break;
                case EDSDK.ObjectEvent_DirItemCreated:
                    if (DownloadVideo) { DownloadImage(inRef, ImageSaveDirectory); DownloadVideo = false; }
                    break;
                case EDSDK.ObjectEvent_DirItemInfoChanged:
                    break;
                case EDSDK.ObjectEvent_DirItemRemoved:
                    break;
                case EDSDK.ObjectEvent_DirItemRequestTransfer:
                    if (ImageReady != null) ImageReady(DownloadImage(inRef));
                    break;
                case EDSDK.ObjectEvent_DirItemRequestTransferDT:
                    break;
                case EDSDK.ObjectEvent_FolderUpdateItems:
                    break;
                case EDSDK.ObjectEvent_VolumeAdded:
                    break;
                case EDSDK.ObjectEvent_VolumeInfoChanged:
                    break;
                case EDSDK.ObjectEvent_VolumeRemoved:
                    break;
                case EDSDK.ObjectEvent_VolumeUpdateItems:
                    break;
            }

            return EDSDK.EDS_ERR_OK;
        }

我切换到的行是:

if (ImageReady != null) ImageReady(DownloadImage(inRef));

在线路上,我在右侧收到错误:

ImageReady(DownloadImage(inRef));

错误是:

错误3参数1:无法转换为&#39; void&#39;到&#39; System.IntPtr&#39;

但是,如果我将从ImageUpdate中删除参数:

public delegate void ImageUpdate();

现在我在同一条线上收到错误:

if (ImageReady != null) ImageReady(DownloadImage(inRef));

这次右侧的错误说:

错误2委托&#39; ImageUpdate&#39;不带1个参数

所以我被困在这里。

这是DownloadImage方法:

/// <summary>
        /// Downloads a jpg image from the camera into a Bitmap. Fires the ImageDownloaded event when done.
        /// </summary>
        /// <param name="ObjectPointer">Pointer to the object. Get it from the SDKObjectEvent.</param>
        public void DownloadImage(IntPtr ObjectPointer)
        {
            //get information about image
            EDSDK.EdsDirectoryItemInfo dirInfo = new EDSDK.EdsDirectoryItemInfo();
            Error = EDSDK.EdsGetDirectoryItemInfo(ObjectPointer, out dirInfo);

            //check the extension. Raw data cannot be read by the bitmap class
            string ext = Path.GetExtension(dirInfo.szFileName).ToLower();
            if (ext == ".jpg" || ext == ".jpeg")
            {
                SendSDKCommand(delegate
                {
                    Bitmap bmp = null;
                    IntPtr streamRef, jpgPointer = IntPtr.Zero;
                    uint length = 0;

                    //create memory stream
                    Error = EDSDK.EdsCreateMemoryStream(dirInfo.Size, out streamRef);

                     //download data to the stream
                     lock (STAThread.ExecLock) { DownloadData(ObjectPointer, streamRef); }
                     Error = EDSDK.EdsGetPointer(streamRef, out jpgPointer);
                     Error = EDSDK.EdsGetLength(streamRef, out length);

                     unsafe
                     {
                         //create a System.IO.Stream from the pointer
                         using (UnmanagedMemoryStream ums = new UnmanagedMemoryStream((byte*)jpgPointer.ToPointer(), length, length, FileAccess.Read))
                         {
                             //create bitmap from stream (it's a normal jpeg image)
                             bmp = new Bitmap(ums);
                         }
                     }

                     //release data
                     Error = EDSDK.EdsRelease(streamRef);

                    //Fire the event with the image
                     if (ImageDownloaded != null) ImageDownloaded(bmp);
                 }, true);
            }
            else
            {
                //if it's a RAW image, cancel the download and release the image
                SendSDKCommand(delegate { Error = EDSDK.EdsDownloadCancel(ObjectPointer); });
                Error = EDSDK.EdsRelease(ObjectPointer);
            }
        }

该项目的所有者回答了第二个错误:

DownloadImage(IntPtr)方法不返回图像(它返回void)。 但是,由于事件期望得到一个图像,它说它不能将void转换为图像。 您需要从具有图像对象的DownloadImage方法中触发该事件。

我不明白该怎么做。 我试图剪切并只显示我遇到问题的代码。

整个项目在这里:

Project

我知道这个问题有一些代码,但我无法解决这个问题。

1 个答案:

答案 0 :(得分:1)

为什么不使用“浏览”按钮1浏览和搜索图像,然后将其显示在图片框上?

        private void Browse_Click(object sender, EventArgs e)
    {
        OpenFileDialog OFD = new OpenFileDialog();
        if (OFD.ShowDialog() == DialogResult.OK)
        {
            Bitmap Image = new Bitmap(OFD.FileName);
            NewUserPictureBox.Image = Image;
            NewUserPictureBox.SizeMode = PictureBoxSizeMode.Zoom;
        }
    }