Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
102 changes: 68 additions & 34 deletions knowledge-base/create-custom-jpeg-image-converter-net-standard.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ res_type: kb
</thead>
<tbody>
<tr>
<td>2023.1.315</td>
<td>up to 2023.1.410</td>
<td>RadPdfProcessing</td>
<td rowspan="2" ><a href="https://www.telerik.com/blogs/author/martin-velikov">Martin Velikov</a></td>
</tr>
Expand All @@ -32,66 +32,100 @@ res_type: kb

## Description

**.NET Standard** specification does not define APIs for converting images or scaling their quality. That is why to export to PDF format a document containing images different than Jpeg and Jpeg2000 or ImageQuality different than High, you will need to provide an implementation of the **JpegImageConverterBase** abstract class. This implementation should be passed to the **JpegImageConverter** property of the **FixedExtensibilityManager**.
**.NET Standard** specification does not define APIs for converting images or scaling their quality. That is why, when inserting images in a PDF document different than Jpeg and Jpeg2000 or ImageQuality different than High, you will need to implement the **JpegImageConverterBase** abstract class. This implementation should be passed to the **JpegImageConverter** property of the **FixedExtensibilityManager**.

>important With the [R2 2023 changes](https://docs.telerik.com/devtools/document-processing/libraries/radpdfprocessing/changes-and-backward-compatibility/backward-compatibility#whats-different-in-2023-r2) SkiaSharp replaced ImageSharp as the required dependency.

## Solution

The following code snippets demonstrate how to create a custom implementation of the JpegImageConverterBase abstract class using the [SixLabors.ImageSharp](https://github.com/SixLabors/ImageSharp) library and set it to the JpegImageConverter property of the FixedExtensibilityManager. We are using the ImageSharp library to convert the images from one of the library's supported formats to Jpeg and to change their quality if it is set.
The following code snippets demonstrate how to create a custom implementation of the JpegImageConverterBase abstract class using the [SixLabors.ImageSharp](https://github.com/SixLabors/ImageSharp) library and set it to the JpegImageConverter property of the FixedExtensibilityManager. We are using the ImageSharp library to convert the images from one of the library's supported formats to Jpeg and to change their quality if it is set. Note that this approach is valid up to version 2023.1.410 of RadPdfProcessing.

#### __[C#] Create a custom implementation inheriting the JpegImageConverterBase abstract class__

{{region kb-create-custom-jpeg-image-converter1}}

internal class JpegImageConverter : JpegImageConverterBase
{
public override bool TryConvertToJpegImageData(byte[] imageData, ImageQuality imageQuality, out byte[] jpegImageData)
public class CustomJpegImageConverter : JpegImageConverterBase
{
try
public override bool TryConvertToJpegImageData(byte[] imageData, ImageQuality imageQuality, out byte[] jpegImageData)
{
IImageFormat imageFormat;
using (SixLabors.ImageSharp.Image image = SixLabors.ImageSharp.Image.Load(imageData, out imageFormat))
try
{
if (imageFormat.GetType() == typeof(PngFormat))
IImageFormat imageFormat;
using (SixLabors.ImageSharp.Image image = SixLabors.ImageSharp.Image.Load(imageData, out imageFormat))
{
image.Mutate(x => x.BackgroundColor(Color.White));
}
if (imageFormat.GetType() == typeof(PngFormat))
{
image.Mutate(x => x.BackgroundColor(Color.White));
}

JpegEncoder options = new JpegEncoder
{
Quality = (int)imageQuality,
};
JpegEncoder options = new JpegEncoder
{
Quality = (int)imageQuality,
};

using (MemoryStream ms = new MemoryStream())
{
image.SaveAsJpeg(ms, options);
using (MemoryStream ms = new MemoryStream())
{
image.SaveAsJpeg(ms, options);

jpegImageData = ms.ToArray();
jpegImageData = ms.ToArray();
}

}
}

return true;
}
catch (Exception ex)
{
if (ex is UnknownImageFormatException || ex is ImageProcessingException)
{
jpegImageData = null;
return false;
return true;
}
else
catch (Exception ex)
{
throw ex;
if (ex is UnknownImageFormatException || ex is ImageProcessingException)
{
jpegImageData = null;
return false;
}
else
{
throw ex;
}
}
}
}
}

{{endregion}}

#### __[C#] Set the custom implementation to the JpegImageConverter property of the FixedExtensibilityManager__

{{region kb-create-custom-jpeg-image-converter2}}

JpegImageConverterBase customJpegImageConverter = new CustomJpegImageConverter();
FixedExtensibilityManager.JpegImageConverter = customJpegImageConverter;
JpegImageConverterBase customJpegImageConverter = new CustomJpegImageConverter();
FixedExtensibilityManager.JpegImageConverter = customJpegImageConverter;

// RadPdfProcessing version up to 2023.1.410
PdfFormatProvider provider = new PdfFormatProvider();
string imageFolderPath = @"..\..\..\images";
string[] imageFiles = Directory.GetFiles(imageFolderPath);
RadFixedDocument fixedDocument = new RadFixedDocument();
RadFixedDocumentEditor documentEditor = new RadFixedDocumentEditor(fixedDocument);

foreach (string imageFilePath in imageFiles)
{
FileStream fileStream = new FileStream(imageFilePath, FileMode.Open);
Telerik.Windows.Documents.Fixed.Model.Resources.ImageSource _imageSource = new Telerik.Windows.Documents.Fixed.Model.Resources.ImageSource(fileStream);
documentEditor.InsertImageInline(_imageSource);
documentEditor.InsertLineBreak();
}

documentEditor.Dispose();
string outputFilePath = @"output.pdf";
File.Delete(outputFilePath);
using (Stream output = File.OpenWrite(outputFilePath))
{
provider.Export(fixedDocument, output);
}

Process.Start(new ProcessStartInfo() { FileName = outputFilePath, UseShellExecute = true });

{{endregion}}


# See Also

- [Cross platform >> Images]({%slug radpdfprocessing-cross-platform-images%})