Kuwait.Lis.PixCrypt 1.0.10

The owner has unlisted this package. This could mean that the package is deprecated, has security vulnerabilities or shouldn't be used anymore.
dotnet add package Kuwait.Lis.PixCrypt --version 1.0.10
                    
NuGet\Install-Package Kuwait.Lis.PixCrypt -Version 1.0.10
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Kuwait.Lis.PixCrypt" Version="1.0.10" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Kuwait.Lis.PixCrypt" Version="1.0.10" />
                    
Directory.Packages.props
<PackageReference Include="Kuwait.Lis.PixCrypt" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Kuwait.Lis.PixCrypt --version 1.0.10
                    
#r "nuget: Kuwait.Lis.PixCrypt, 1.0.10"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Kuwait.Lis.PixCrypt@1.0.10
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Kuwait.Lis.PixCrypt&version=1.0.10
                    
Install as a Cake Addin
#tool nuget:?package=Kuwait.Lis.PixCrypt&version=1.0.10
                    
Install as a Cake Tool

Kuwait.Lis.PixCrypt

A .NET library for media encryption and cloud storage operations for Kuwait LIS services.

Features

  • Media Encryption/Decryption: AES encryption using CryptoStream for memory-efficient streaming
  • Media Compression:
    • Images: Quality-aware re-encoding (JPEG, PNG, WebP, GIF, BMP) with size guard — never returns a larger file than the original
    • Videos: H.264/H.265 transcoding via FFmpeg (50–80% size reduction)
    • Documents: GZip compression for PDF, DOC, XLS, etc.
  • Auto FFmpeg Installation: Automatically downloads FFmpeg binaries on first use (thread-safe, one-time)
  • Azure Blob Storage: Upload, download, and delete files from Azure using BlockBlobClient
  • AWS S3 Storage: Upload, download, and delete files from AWS S3 with cached client instances
  • Chunk Upload: Large file upload with chunking support (Azure & AWS) with automatic session expiry (2 hours)
  • AWS S3 Multipart Upload: Native S3 multipart chunk upload without full-file buffering
  • Dependency Injection: First-class DI support via AddPixCrypt() extension
  • Typed Storage Options: Separate AzureStorageOptions and AwsStorageOptions for compile-time safety
  • Plug & Play: All credentials passed at runtime — no configuration files needed

Installation

dotnet add package Kuwait.Lis.PixCrypt

Dependency Injection Setup

Register all PixCrypt services in your DI container:

// Program.cs / Startup.cs
builder.Services.AddPixCrypt();

Then inject services directly:

public class MyService
{
    private readonly MediaEncryptionService _encryption;
    private readonly MediaCompressionService _compression;

    public MyService(MediaEncryptionService encryption, MediaCompressionService compression)
    {
        _encryption = encryption;
        _compression = compression;
    }
}

Or use the static PixCryptHelper facade for quick usage without DI.

Usage

Media Compression

Image Compression
using Kuwait.Lis.PixCrypt.Helpers;

// Compress image (re-encodes at quality 80)
// Returns original bytes if re-encoded result is larger (e.g. already-compressed JPEG)
byte[] compressed = await PixCryptHelper.CompressBytesAsync(imageData, "photo.jpg", imageQuality: 80);

// Decompress (for GZip-compressed files only, not needed for images)
byte[] original = PixCryptHelper.DecompressBytes(compressed);
Video Compression (FFmpeg)
using Kuwait.Lis.PixCrypt.Helpers;
using Kuwait.Lis.PixCrypt.Models;

// Basic video compression (H.264, CRF 28, auto-download FFmpeg if needed)
byte[] compressed = await PixCryptHelper.CompressBytesAsync(videoData, "video.mp4");

// Advanced video compression with custom options
var videoOptions = new VideoCompressionOptions
{
    Codec = VideoCodec.H265,                    // H264 or H265 (better compression)
    Crf = 28,                                   // Quality: 0 (best) – 51 (worst). Recommended: 23–30
    Preset = EncodingPreset.Fast,               // Speed vs compression trade-off
    MaxResolution = new VideoResolution
    {
        Width = 1280,
        Height = 720
    },
    AudioBitrateKbps = 128,                     // Audio quality (0 = strip audio)
    FfmpegPath = "/app/ffmpeg-bins"             // Optional: persistent FFmpeg location
};

byte[] compressed = await PixCryptHelper.CompressBytesAsync(
    videoData,
    "large-video.mp4",
    videoOptions: videoOptions
);

FFmpeg Auto-Installation:

  • FFmpeg binaries are automatically downloaded on first use (~70MB, one-time)
  • Initialization is thread-safe — concurrent calls will not trigger duplicate downloads
  • Default download location: %TEMP%/ffmpeg/ (may be cleared on server restart)
  • For production: set FfmpegPath to a persistent directory to avoid re-downloading

Video Compression Results:

  • Typical size reduction: 50–80% depending on CRF and codec
  • H.265 provides ~30% better compression than H.264 but slower encoding
  • CRF 28 = good balance of quality and size
  • Higher CRF = smaller file, lower quality
Document Compression
// Compress PDF/DOC/XLS with GZip (lossless)
byte[] compressed = await PixCryptHelper.CompressBytesAsync(pdfData, "document.pdf");

// Decompress
byte[] original = PixCryptHelper.DecompressBytes(compressed);

Media Encryption

Encryption uses CryptoStream internally for efficient handling of large files:

using Kuwait.Lis.PixCrypt.Services;
using Kuwait.Lis.PixCrypt.Models;

var encryptionService = new MediaEncryptionService();

var options = new EncryptionOptions
{
    Key = "your-base64-key",
    IV = "your-base64-iv"
};

// Encrypt bytes
byte[] encrypted = encryptionService.Encrypt(imageData, options);

// Decrypt bytes
byte[] decrypted = encryptionService.Decrypt(encrypted, options);

// Encrypt from stream (memory-efficient for large files)
await using var fileStream = File.OpenRead("large-file.bin");
byte[] encrypted = await encryptionService.EncryptAsync(fileStream, options, cancellationToken);

Typed Storage Options

Use AzureStorageOptions or AwsStorageOptions for compile-time validation instead of the base StorageOptions:

// Azure — required properties enforced at compile time
var azureOptions = new AzureStorageOptions
{
    AzureConnectionString = "your-connection-string",
    AzureContainerName = "your-container"
};

// AWS — required properties enforced at compile time
var awsOptions = new AwsStorageOptions
{
    AwsAccessKeyId = "your-access-key",
    AwsSecretAccessKey = "your-secret-key",
    AwsBucketName = "your-bucket",
    AwsRegion = "us-east-1"
};

Azure Storage

using Kuwait.Lis.PixCrypt.Helpers;
using Kuwait.Lis.PixCrypt.Models;

// Upload with video compression
var result = await PixCryptHelper.UploadToAzureAsync(
    filePath: "large-video.mp4",
    connectionString: "your-connection-string",
    containerName: "your-container",
    compress: true,
    videoOptions: new VideoCompressionOptions { Codec = VideoCodec.H265, Crf = 28 }
);

// Upload with encryption + compression
var result = await PixCryptHelper.UploadToAzureAsync(
    filePath: "video.mp4",
    connectionString: "your-connection-string",
    containerName: "your-container",
    encryptionKey: "your-key",
    encryptionIV: "your-iv",
    compress: true,
    videoOptions: new VideoCompressionOptions { Crf = 30 }
);

// Download
string outputPath = await PixCryptHelper.DownloadFromAzureAsync(
    fileName: "video.mp4",
    destinationFolderPath: "/downloads",
    connectionString: "your-connection-string",
    containerName: "your-container"
);

// Download and decrypt
string outputPath = await PixCryptHelper.DownloadAndDecryptFromAzureAsync(
    fileName: "video.mp4",
    destinationFolderPath: "/downloads",
    connectionString: "your-connection-string",
    containerName: "your-container",
    encryptionKey: "your-key",
    encryptionIV: "your-iv"
);

// Delete
bool deleted = await PixCryptHelper.DeleteFromAzureAsync(
    fileName: "video.mp4",
    connectionString: "your-connection-string",
    containerName: "your-container"
);

AWS S3 Storage

AWS S3 clients are cached per accessKeyId + region — no new client is created per call:

var result = await PixCryptHelper.UploadToAwsAsync(
    filePath: "large-video.mp4",
    accessKeyId: "your-access-key",
    secretAccessKey: "your-secret-key",
    bucketName: "your-bucket",
    region: "us-east-1",
    compress: true,
    videoOptions: new VideoCompressionOptions
    {
        Codec = VideoCodec.H265,
        Crf = 28,
        MaxResolution = new VideoResolution { Width = 1920, Height = 1080 }
    }
);

// Download
string outputPath = await PixCryptHelper.DownloadFromAwsAsync(
    fileName: "large-video.mp4",
    destinationFolderPath: "/downloads",
    accessKeyId: "your-access-key",
    secretAccessKey: "your-secret-key",
    bucketName: "your-bucket",
    region: "us-east-1"
);

// Delete
bool deleted = await PixCryptHelper.DeleteFromAwsAsync(
    fileName: "large-video.mp4",
    accessKeyId: "your-access-key",
    secretAccessKey: "your-secret-key",
    bucketName: "your-bucket",
    region: "us-east-1"
);

Chunk Upload (Azure)

Sessions are automatically expired after 2 hours if not completed:

var result = await PixCryptHelper.ChunkUploadToAzureAsync(
    filePath: "huge-video.mp4",
    connectionString: "your-connection-string",
    containerName: "your-container",
    compress: true,
    videoOptions: new VideoCompressionOptions
    {
        Codec = VideoCodec.H265,
        Crf = 30,
        Preset = EncodingPreset.Fast
    },
    chunkSizeBytes: 5 * 1024 * 1024  // 5MB chunks
);

AWS S3 Multipart Chunk Upload

Uses native S3 multipart upload — parts are uploaded directly to S3 without full-file reassembly in memory:

var result = await PixCryptHelper.ChunkUploadToAwsAsync(
    filePath: "huge-video.mp4",
    accessKeyId: "your-access-key",
    secretAccessKey: "your-secret-key",
    bucketName: "your-bucket",
    region: "us-east-1",
    compress: true,
    videoOptions: new VideoCompressionOptions { Codec = VideoCodec.H265, Crf = 28 },
    chunkSizeBytes: 5 * 1024 * 1024
);

Combined: Compress, Encrypt & Upload

// Full pipeline: compress video → encrypt → upload to S3
var result = await PixCryptHelper.UploadToAwsAsync(
    filePath: "sensitive-video.mp4",
    accessKeyId: "your-access-key",
    secretAccessKey: "your-secret-key",
    bucketName: "your-bucket",
    region: "us-east-1",
    encryptionKey: "your-encryption-key",
    encryptionIV: "your-encryption-iv",
    compress: true,
    videoOptions: new VideoCompressionOptions
    {
        Codec = VideoCodec.H265,
        Crf = 28,
        MaxResolution = new VideoResolution { Width = 1280, Height = 720 },
        AudioBitrateKbps = 128
    }
);

Video Compression Configuration

VideoCompressionOptions Properties

Property Type Default Description
FfmpegPath string? null Path to FFmpeg binaries. If null, auto-downloads to %TEMP%/ffmpeg/
Codec VideoCodec H264 H264 (wider support) or H265 (better compression)
Crf int 28 Quality: 0 (lossless) – 51 (worst). H264: 23–28, H265: 24–30
Preset EncodingPreset Medium Speed vs compression: Ultrafast, Fast, Medium, Slow, Veryslow
MaxResolution VideoResolution? null Cap resolution (e.g., 1280x720). Null = keep original
AudioBitrateKbps int 128 Audio quality in kbps. Set to 0 to strip audio

High Quality (minimal compression):

new VideoCompressionOptions { Codec = VideoCodec.H265, Crf = 23, Preset = EncodingPreset.Slow }

Balanced (recommended for most cases):

new VideoCompressionOptions { Codec = VideoCodec.H265, Crf = 28, Preset = EncodingPreset.Medium }

Maximum Compression (smaller files, lower quality):

new VideoCompressionOptions { Codec = VideoCodec.H265, Crf = 32, Preset = EncodingPreset.Fast }

Mobile/Web Optimized:

new VideoCompressionOptions
{
    Codec = VideoCodec.H264,  // Better browser support
    Crf = 28,
    MaxResolution = new VideoResolution { Width = 1280, Height = 720 },
    AudioBitrateKbps = 96
}

FFmpeg Installation

No action needed — FFmpeg binaries are automatically downloaded on first video compression (~70MB, one-time). The initialization is protected by a SemaphoreSlim so concurrent requests will not trigger duplicate downloads.

Manual Installation (Optional)

Linux:

apt-get install ffmpeg

Windows:

  1. Download from ffmpeg.org
  2. Set FfmpegPath in VideoCompressionOptions to the directory containing the binaries

Docker:

RUN apt-get update && apt-get install -y ffmpeg

Production Recommendation

Set a persistent FfmpegPath to avoid re-downloading on every app restart:

var videoOptions = new VideoCompressionOptions
{
    FfmpegPath = "/app/ffmpeg-bins",  // Persistent across restarts
    Codec = VideoCodec.H265,
    Crf = 28
};

Build and Package

# Build
dotnet build --configuration Release

# Pack
dotnet pack --configuration Release --output ./packages

# Push to NuGet (optional)
dotnet nuget push ./packages/Kuwait.Lis.PixCrypt.1.0.0.nupkg --api-key YOUR_API_KEY --source https://api.nuget.org/v3/index.json

Dependencies

  • .NET 10.0
  • Azure.Storage.Blobs (12.24.0)
  • AWSSDK.S3 (3.7.408)
  • SixLabors.ImageSharp (3.1.12)
  • Xabe.FFmpeg (6.0.2)
  • Xabe.FFmpeg.Downloader (6.0.2)
  • Microsoft.Extensions.DependencyInjection.Abstractions (10.0.0)

Performance Considerations

  • Image compression: Returns original bytes if re-encoded result is larger — no unnecessary overhead
  • Encryption: Uses CryptoStream for streaming — avoids doubling memory usage on large files
  • AWS S3 client: Cached per accessKeyId + region — eliminates connection pool exhaustion under load
  • Video compression: CPU-intensive, async (time depends on video length and preset)
    • 1-minute 1080p video: ~10–30 seconds with Medium preset
    • Use Fast or Ultrafast preset for faster encoding (larger output files)
  • Large videos (>100MB): Use chunk upload to avoid memory pressure
  • FFmpeg download: ~70MB, happens once per server lifetime (or per restart if using %TEMP%)
  • Chunk sessions: Automatically purged after 2 hours to prevent memory leaks from abandoned uploads

License

MIT License

Product Compatible and additional computed target framework versions.
.NET net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated