←Select platform

Transform Method

Summary

Performs a lossless transformation for certain formats.

Syntax

C#
C++/CLI
Java
Python
public void transform(String srcFileName, String destFileName, CodecsTransformFlags flags, int pageNumber, CodecsTransformMarkerListener callback) 
def Transform(self,callback): 

Parameters

srcFileName
A String containing the name of the source file.

destFileName
A String containing the name of the destination file.

flags
Indicates the transform to be performed. Possible values are:

Value Meaning
CodecsTransformFlags.Flip Flip the image vertically
CodecsTransformFlags.Reverse Reverse the image (flip horizontally)
CodecsTransformFlags.Rotate90 Rotate the image clockwise by 90 degrees
CodecsTransformFlags.Rotate180 Rotate the image clockwise by 180 degrees
CodecsTransformFlags.Rotate270 Rotate the image clockwise by 270 degrees
CodecsTransformFlags.None Do nothing

pageNumber
1-based index of the page within the source file to process.

callback
Optional callback method for processing custom markers. (This is useful for rotating JPEG files only). When transforming JPEG files, the method will enumerate all the markers contained in the file and it will pass them to this callback. The user has the ability to control the transformation for all of the markers. For additional information on JPEG markers, please consult the JPEG specification.

Remarks

Currently, only JPEG, CMP, JPEG TIFF and HEIF/HEIC formats are supported.

Only one of the rotate flags can be specified.

The files transformed by this method will be read transformed by other applications capable of reading these file formats.

JPEG and Exif JPEG stamps are transformed according to the flags specified in  flags. Please note that some JPEG stamps will not be transformed by this method. Specifically, stamps stored in markers other than APP0 and APP1 will not be transformed. Use the  callback parameter to handle these cases. For example, if a stamp is in the APP14 marker, check for this in the  callback and write your own stamp using SaveStamp.

For JPEG files, the size of the image might be changed. The image width and height is adjusted to be a multiple of 8 or 16 depending on the subsampling present in the image. If the image is 4:4:4, the width and height is adjusted to be a multiple of 16. If the image is 422, the original width is adjusted to be a multiple of 16 and the height to be a multiple of 8. After rotation, the width might become height. If the image is 411, the width and height are adjusted to be a multiple of 16.

The transformation is lossless. It is better than loading the image, transforming it using RotateCommand or FlipCommand and resaving it. Repeated load and save process will cause image degradation, but calling this method will not cause any image degradation.

The rotation transformations are performed before the flip/reverse operations.

Use the WriteTransformMarker method to control how the transform markers are used.

Example

This example will use the JPEG transformation to rotate a file by 90 degrees.

C#
Java
using Leadtools; 
using Leadtools.Codecs; 
using Leadtools.ImageProcessing; 
using Leadtools.ImageProcessing.Color; 
using Leadtools.Svg; 
 
 
public void TransformExample() 
{ 
   RasterCodecs codecs = new RasterCodecs(); 
 
   string srcFileName = Path.Combine(LEAD_VARS.ImagesDir, "Image1.cmp"); 
 
   string destFileName = Path.Combine(LEAD_VARS.ImagesDir, "Image1_Transform.cmp"); 
 
 
   // Load the source image with markers 
   Debug.WriteLine("Loading the source image with all markers"); 
   codecs.Options.Load.Markers = true; 
   RasterImage srcImage = codecs.Load(srcFileName); 
 
   // Show the markers loaded, if any 
   Debug.WriteLine("These markers were loaded:"); 
   foreach (RasterMarkerMetadata marker in srcImage.Markers) 
   { 
      byte[] data = marker.GetData(); 
      codecs.WriteMarker(srcFileName, 1, marker); 
      // codecs.WriteMarker(stream, 1, marker); 
      codecs.WriteTransformMarker(marker.Id, data, 0, 1); 
      Debug.WriteLine(" {0}, DataSize:{1}", marker.Id, data.Length); 
   } 
 
   codecs.Transform( 
      srcFileName, 
      destFileName, 
      CodecsTransformFlags.Rotate90, 
      1, 
      CodecsTransformMarkerCallback); 
 
   // Clean up 
   codecs.Dispose(); 
} 
 
CodecsTransformMarkerAction CodecsTransformMarkerCallback(int id, RasterNativeBuffer buffer, CodecsTransformFlags transform) 
{ 
   Debug.WriteLine("Transforming: id: {0}, Data Length: {1}, transform: {2}", id, buffer.Length, transform); 
   return CodecsTransformMarkerAction.Default; 
} 
 
static class LEAD_VARS 
{ 
   public const string ImagesDir = @"C:\LEADTOOLS23\Resources\Images"; 
} 
 
import java.io.*; 
import java.net.*; 
import java.nio.file.Paths; 
import java.util.*; 
import java.time.Instant; 
import java.time.Duration; 
 
import org.junit.*; 
import org.junit.runner.JUnitCore; 
import org.junit.runner.Result; 
import org.junit.runner.notification.Failure; 
import static org.junit.Assert.*; 
 
import leadtools.*; 
import leadtools.codecs.*; 
import leadtools.codecs.RasterCodecs.FeedCallbackThunk; 
import leadtools.drawing.internal.*; 
import leadtools.imageprocessing.*; 
import leadtools.imageprocessing.color.ChangeIntensityCommand; 
import leadtools.svg.*; 
 
 
RasterCodecs codecs; 
 
public void transformExample() { 
   final String LEAD_VARS_IMAGES_DIR = "C:\\LEADTOOLS23\\Resources\\Images"; 
   codecs = new RasterCodecs(); 
 
   String srcFileName = combine(LEAD_VARS_IMAGES_DIR, "Image1.cmp"); 
   String destFileName = combine(LEAD_VARS_IMAGES_DIR, "Image1_Transform.cmp"); 
 
   // Load the source image with markers 
   System.out.println("Loading the source image with all markers"); 
   codecs.getOptions().getLoad().setMarkers(true); 
   RasterImage srcImage = codecs.load(srcFileName); 
 
   // Show the markers loaded, if any 
   System.out.println("These markers were loaded:"); 
 
   for (RasterMarkerMetadata marker : srcImage.getMarkers()) { 
      byte[] data = marker.getData(); 
      ILeadStream srcFileStream = LeadStreamFactory.create(srcFileName); 
      codecs.writeMarker(srcFileStream, 1, marker); 
      codecs.transform(srcFileName, destFileName, CodecsTransformFlags.ROTATE_90, 1, CodecsTransformMarkerCallback); 
      System.out.printf(" %s, DataSize:%s%m", marker.getId(), data.length); 
   } 
 
   // Clean up 
   codecs.dispose(); 
} 
 
CodecsTransformMarkerListener CodecsTransformMarkerCallback = new CodecsTransformMarkerListener() { 
 
   @Override 
   public CodecsTransformMarkerAction OnCodecsTransformMarkerCallback(int id, RasterNativeBuffer buffer, 
         CodecsTransformFlags transform) { 
      buffer.getData(); 
      codecs.writeTransformMarker(id, buffer.getData(), 1, 1); 
      System.out.printf("Transforming: id: %s, Data Length: %s, transform: %s%n", id, buffer.getLength(), transform); 
      return CodecsTransformMarkerAction.DEFAULT; 
   } 
 
}; 

Requirements

Target Platforms

See Also

RasterCodecs Class

RasterCodecs Members

Working with Markers

Introduction to Image Processing With LEADTOOLS

Help Version 23.0.2024.2.29
Products | Support | Contact Us | Intellectual Property Notices
© 1991-2024 LEAD Technologies, Inc. All Rights Reserved.

Leadtools.Codecs Assembly
Products | Support | Contact Us | Intellectual Property Notices
© 1991-2023 LEAD Technologies, Inc. All Rights Reserved.