-
Notifications
You must be signed in to change notification settings - Fork 126
Open
Labels
Description
I'm using the following code to save images to JPG compressed TIFs.
This works if the width of the input image is divisible by 8. If it's not, then the image will be skewed.
Using memStream As New IO.MemoryStream()
Using output As BitMiracle.LibTiff.Classic.Tiff = BitMiracle.LibTiff.Classic.Tiff.ClientOpen("in-memory", "w", memStream, New BitMiracle.LibTiff.Classic.TiffStream())
Dim page As Integer = 0
Dim pages As Integer = InputImages.Count
For Each inImage As Drawing.Image In InputImages
output.SetField(BitMiracle.LibTiff.Classic.TiffTag.IMAGEWIDTH, inImage.Width)
output.SetField(BitMiracle.LibTiff.Classic.TiffTag.IMAGELENGTH, inImage.Height)
output.SetField(BitMiracle.LibTiff.Classic.TiffTag.COMPRESSION, BitMiracle.LibTiff.Classic.Compression.JPEG)
output.SetField(BitMiracle.LibTiff.Classic.TiffTag.PHOTOMETRIC, BitMiracle.LibTiff.Classic.Photometric.YCBCR)
output.SetField(BitMiracle.LibTiff.Classic.TiffTag.SUBFILETYPE, BitMiracle.LibTiff.Classic.FileType.PAGE)
output.SetField(BitMiracle.LibTiff.Classic.TiffTag.ROWSPERSTRIP, inImage.Height)
output.SetField(BitMiracle.LibTiff.Classic.TiffTag.ORIENTATION, BitMiracle.LibTiff.Classic.Orientation.TOPLEFT)
output.SetField(BitMiracle.LibTiff.Classic.TiffTag.XRESOLUTION, inImage.HorizontalResolution)
output.SetField(BitMiracle.LibTiff.Classic.TiffTag.YRESOLUTION, inImage.VerticalResolution)
output.SetField(BitMiracle.LibTiff.Classic.TiffTag.RESOLUTIONUNIT, BitMiracle.LibTiff.Classic.ResUnit.INCH)
output.SetField(BitMiracle.LibTiff.Classic.TiffTag.BITSPERSAMPLE, 8)
output.SetField(BitMiracle.LibTiff.Classic.TiffTag.SAMPLESPERPIXEL, 3)
output.SetField(BitMiracle.LibTiff.Classic.TiffTag.PLANARCONFIG, BitMiracle.LibTiff.Classic.PlanarConfig.CONTIG)
output.SetField(BitMiracle.LibTiff.Classic.TiffTag.YCBCRPOSITIONING, 1)
output.SetField(BitMiracle.LibTiff.Classic.TiffTag.YCBCRSUBSAMPLING, 1, 1)
output.SetField(BitMiracle.LibTiff.Classic.TiffTag.JPEGTABLESMODE, BitMiracle.LibTiff.Classic.JpegTablesMode.NONE)
output.SetField(BitMiracle.LibTiff.Classic.TiffTag.PAGENUMBER, page, pages)
Dim bytes As Byte() = GetImageRasterBytes(CType(inImage, Bitmap), PixelFormat.Format24bppRgb)
convertSamples(bytes, inImage.Width, inImage.Height)
output.WriteEncodedStrip(0, bytes, bytes.Length)
page += 1
output.WriteDirectory()
Next
output.Close()
Dim byteArray() As Byte = memStream.ToArray()
Return byteArray
End Using
End UsingThe helper functions i have are as follows:
Private Function GetImageRasterBytes(ByVal bmp As Bitmap, ByVal format As PixelFormat) As Byte()
Dim rect = New Rectangle(0, 0, bmp.Width, bmp.Height)
Dim bits As Byte()
Try
Dim bmpdata = bmp.LockBits(rect, ImageLockMode.ReadWrite, format)
bits = New Byte(bmpdata.Stride * bmpdata.Height - 1) {}
System.Runtime.InteropServices.Marshal.Copy(bmpdata.Scan0, bits, 0, bits.Length)
bmp.UnlockBits(bmpdata)
Catch
Return Nothing
End Try
Return bits
End Function
Private Sub convertSamples(ByVal data As Byte(), ByVal width As Integer, ByVal height As Integer)
Dim stride As Integer = data.Length \ height
Const samplesPerPixel As Integer = 3
For y As Integer = 0 To height - 1
Dim offset As Integer = stride * y
Dim strideEnd As Integer = offset + width * samplesPerPixel
Dim i As Integer = offset
While i <strideEnd
Dim temp As Byte = data(i + 2)
data(i + 2) = data(i)
data(i) = temp
i += samplesPerPixel
End While
Next
End SubIf you run the above the 1040x800 document will look fine.
The same code will result in a skewed output for the 1035x800 one.

In addition, when this skewing happens, the console does print out a warning:
in-memory: Warning, fractional scanline discarded
Anyone have any idea what may be going on, and how I can fix this?