// Don't use this method to create image with unknown/unspecified stride (like MJPEG). // For such formats, size of image in bytes must be specified to create image. public Image(ImageFormat format, int widthPixels, int heightPixels, int strideBytes) { if (widthPixels <= 0) { throw new ArgumentOutOfRangeException(nameof(widthPixels)); } if (heightPixels <= 0) { throw new ArgumentOutOfRangeException(nameof(heightPixels)); } if (strideBytes < 0) { throw new ArgumentOutOfRangeException(nameof(strideBytes)); } if (strideBytes == 0) { throw new InvalidOperationException("Zero stride is used for formats without complex structure like MJPEG. In this case size of image in bytes must be specified to create image."); } if (format.HasKnownBytesPerPixel() && strideBytes < widthPixels * format.BytesPerPixel()) { throw new ArgumentOutOfRangeException(nameof(strideBytes)); } var res = NativeApi.ImageCreate(format, widthPixels, heightPixels, strideBytes, out var handle); if (res != NativeCallResults.Result.Succeeded || handle == null || handle.IsInvalid) { throw new ArgumentException($"Cannot create image with format {format}, size {widthPixels}x{heightPixels} pixels and stride {strideBytes} bytes."); } this.handle = handle; this.handle.Disposed += Handle_Disposed; }
/// <summary>Creates new image with specified format, size in pixels and stride in bytes.</summary> /// <param name="format">Format of image. Must be format with known stride: <see cref="ImageFormats.StrideBytes(ImageFormat, int)"/>.</param> /// <param name="widthPixels">Width of image in pixels. Must be positive.</param> /// <param name="heightPixels">Height of image in pixels. Must be positive.</param> /// <param name="strideBytes">Image stride in bytes (the number of bytes per horizontal line of the image). Must be non-negative. Zero value can be used for <see cref="ImageFormat.ColorMjpg"/> and <see cref="ImageFormat.Custom"/>.</param> /// <param name="sizeBytes">Size of image buffer in size. Non negative. Cannot be less than size calculated from image parameters.</param> /// <exception cref="ArgumentOutOfRangeException"> /// <paramref name="widthPixels"/> or <paramref name="heightPixels"/> is equal to or less than zero /// or <paramref name="strideBytes"/> is less than zero or <paramref name="strideBytes"/> is too small for specified <paramref name="format"/> /// or <paramref name="sizeBytes"/> is less than zero or <paramref name="sizeBytes"/> is less than size calculated from <paramref name="heightPixels"/> and <paramref name="strideBytes"/>. /// </exception> /// <exception cref="InvalidOperationException"> /// <paramref name="strideBytes"/> is equal to zero. In this case size of image in bytes must be specified to create image. /// </exception> public Image(ImageFormat format, int widthPixels, int heightPixels, int strideBytes, int sizeBytes) { if (widthPixels <= 0) { throw new ArgumentOutOfRangeException(nameof(widthPixels)); } if (heightPixels <= 0) { throw new ArgumentOutOfRangeException(nameof(heightPixels)); } if (strideBytes < 0) { throw new ArgumentOutOfRangeException(nameof(strideBytes)); } if (format.HasKnownBytesPerPixel() && strideBytes < widthPixels * format.BytesPerPixel()) { throw new ArgumentOutOfRangeException(nameof(strideBytes)); } if (sizeBytes <= 0) { throw new ArgumentOutOfRangeException(nameof(sizeBytes)); } if (strideBytes > 0 && sizeBytes < format.ImageSizeBytes(strideBytes, heightPixels)) { throw new ArgumentOutOfRangeException(nameof(sizeBytes)); } var buffer = Marshal.AllocHGlobal(sizeBytes); if (buffer == IntPtr.Zero) { throw new OutOfMemoryException($"Cannot allocate buffer of {sizeBytes} bytes."); } var res = NativeApi.ImageCreateFromBuffer(format, widthPixels, heightPixels, strideBytes, buffer, Helpers.Int32ToUIntPtr(sizeBytes), unmanagedBufferReleaseCallback, IntPtr.Zero, out var handle); if (res != NativeCallResults.Result.Succeeded || handle == null || handle.IsInvalid) { throw new ArgumentException($"Cannot create image with format {format}, size {widthPixels}x{heightPixels} pixels, stride {strideBytes} bytes from buffer of size {sizeBytes} bytes."); } this.handle = handle; this.handle.Disposed += Handle_Disposed; }
/// <summary>Creates new image for specified underlying buffer with specified format and size in pixels.</summary> /// <typeparam name="T">Type of array elements in underlying buffer. Must be value type.</typeparam> /// <param name="buffer">Underlying buffer for image. Cannot be <see langword="null"/>. Object will pin and keep reference to this array during all lifetime.</param> /// <param name="format">Format of image.</param> /// <param name="widthPixels">Width of image in pixels. Must be positive.</param> /// <param name="heightPixels">Height of image in pixels. Must be positive.</param> /// <param name="strideBytes">Image stride in bytes (the number of bytes per horizontal line of the image). Must be non-negative. Zero value can be used for <see cref="ImageFormat.ColorMjpg"/> and <see cref="ImageFormat.Custom"/>.</param> /// <returns>Created image. Not <see langword="null"/>.</returns> /// <remarks><para> /// <see cref="Buffer"/> points to pinned array <paramref name="buffer"/> for such images. /// </para></remarks> /// <exception cref="ArgumentOutOfRangeException"> /// <paramref name="widthPixels"/> or <paramref name="heightPixels"/> is equal to or less than zero /// or <paramref name="strideBytes"/> is less than zero or <paramref name="strideBytes"/> is too small for specified <paramref name="format"/> /// or <paramref name="buffer"/> array is too small for specified image parameters. /// </exception> public static Image CreateFromArray <T>(T[] buffer, ImageFormat format, int widthPixels, int heightPixels, int strideBytes) where T : struct { if (buffer == null) { throw new ArgumentNullException(nameof(buffer)); } if (widthPixels <= 0) { throw new ArgumentOutOfRangeException(nameof(widthPixels)); } if (heightPixels <= 0) { throw new ArgumentOutOfRangeException(nameof(heightPixels)); } if (strideBytes < 0) { throw new ArgumentOutOfRangeException(nameof(strideBytes)); } if (format.HasKnownBytesPerPixel() && strideBytes < widthPixels * format.BytesPerPixel()) { throw new ArgumentOutOfRangeException(nameof(strideBytes)); } var sizeBytes = buffer.Length * Marshal.SizeOf <T>(); if (strideBytes > 0 && sizeBytes < format.ImageSizeBytes(strideBytes, heightPixels)) { throw new ArgumentOutOfRangeException(nameof(buffer) + "." + nameof(buffer.Length)); } var bufferPin = GCHandle.Alloc(buffer, GCHandleType.Pinned); var bufferPtr = bufferPin.AddrOfPinnedObject(); var res = NativeApi.ImageCreateFromBuffer(format, widthPixels, heightPixels, strideBytes, bufferPtr, Helpers.Int32ToUIntPtr(sizeBytes), pinnedArrayReleaseCallback, (IntPtr)bufferPin, out var handle); if (res != NativeCallResults.Result.Succeeded || handle == null || handle.IsInvalid) { throw new ArgumentException($"Cannot create image with format {format}, size {widthPixels}x{heightPixels} pixels, stride {strideBytes} bytes from buffer of size {sizeBytes} bytes."); } return(Create(handle)); }
/// <summary>Creates new image with specified format, size in pixels and stride in bytes.</summary> /// <param name="format">Format of image. Must be format with known stride: <see cref="ImageFormats.StrideBytes(ImageFormat, int)"/>.</param> /// <param name="widthPixels">Width of image in pixels. Must be positive.</param> /// <param name="heightPixels">Height of image in pixels. Must be positive.</param> /// <param name="strideBytes">Image stride in bytes (the number of bytes per horizontal line of the image). Must be positive.</param> /// <remarks> /// Don't use this method to create image with unknown/unspecified stride (like MJPEG). /// For such formats, size of image in bytes must be specified to create image: <see cref="Image.Image(ImageFormat, int, int, int, int)"/>. /// </remarks> /// <exception cref="ArgumentOutOfRangeException"> /// <paramref name="widthPixels"/> or <paramref name="heightPixels"/> is equal to or less than zero /// or <paramref name="strideBytes"/> is less than zero or <paramref name="strideBytes"/> is too small for specified <paramref name="format"/>. /// </exception> /// <exception cref="InvalidOperationException"> /// <paramref name="strideBytes"/> is equal to zero. In this case size of image in bytes must be specified to create image. /// </exception> /// <exception cref="NotSupportedException"> /// If <paramref name="format"/> equals to <see cref="ImageFormat.ColorNV12"/>. /// For details see https://github.com/microsoft/Azure-Kinect-Sensor-SDK/issues/587. /// </exception> public Image(ImageFormat format, int widthPixels, int heightPixels, int strideBytes) { if (widthPixels <= 0) { throw new ArgumentOutOfRangeException(nameof(widthPixels)); } if (heightPixels <= 0) { throw new ArgumentOutOfRangeException(nameof(heightPixels)); } if (strideBytes < 0) { throw new ArgumentOutOfRangeException(nameof(strideBytes)); } if (strideBytes == 0) { throw new InvalidOperationException("Zero stride is used for formats with complex structure like MJPEG. In this case size of image in bytes must be specified to create image."); } if (format.HasKnownBytesPerPixel() && strideBytes < widthPixels * format.BytesPerPixel()) { throw new ArgumentOutOfRangeException(nameof(strideBytes)); } if (format == ImageFormat.ColorNV12) { // Because of bug in Sensor DK // See https://github.com/microsoft/Azure-Kinect-Sensor-SDK/issues/587 throw new NotSupportedException($"Please, specify size of image data in bytes for {format} format. This is because of issue #587 in Sensor DK."); } var res = NativeApi.ImageCreate(format, widthPixels, heightPixels, strideBytes, out var handle); if (res != NativeCallResults.Result.Succeeded || handle == null || handle.IsInvalid) { throw new ArgumentException($"Cannot create image with format {format}, size {widthPixels}x{heightPixels} pixels and stride {strideBytes} bytes."); } this.handle = handle; this.handle.Disposed += Handle_Disposed; }