У меня есть программа, которая преобразует документы RTF в изображения Tiff для отправки факсов.В настоящее время он использует Word для сохранения документа в формате PDF, а затем я конвертирую его в TIFF.Это вызывает проблемы с лицензированием на серверах Citrix, и нам нужно другое решение.Я начал добиваться некоторого успеха с этим кодом, но столкнулся с двумя проблемами.Первая и самая большая проблема заключается в том, что это удаляет заголовки из документов.Во-вторых, когда страница не является полной страницей, остальная часть страницы будет расположена внизу.Я знаю, что Первая проблема вызвана тем, что RealTextBox удаляет заголовки.Во-вторых, вероятно, я настроил свой цикл, но я не слишком беспокоюсь об этом, пока не найду способ иметь заголовки в изображениях.
Я создал простое консольное приложение длятестирование, так как остальная часть программы в порядке, это просто конверсия, с которой у меня проблемы.Весь код ниже.Я собрал его с нескольких форумов помощи, и на данный момент я просто застрял.Я сделал жесткий код размеров для размера страницы и полей, но у меня есть то, что раньше было закомментировано рядом с ними.Я не знаю, нужно ли мне идти другим путем или просто нужно использовать какой-то другой обработчик или что-то еще, чтобы заголовки не были удалены.Любая помощь очень ценится.
using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Runtime.InteropServices;
using System.Windows.Forms;
namespace RTFtoImageTest
{
class Program
{
static void Main(string[] args)
{
try
{
string text = File.ReadAllText(@"C:\Test\TestRTFWithHeader.rtf");
RichTextBox rtb = new RichTextBox();
rtb.Rtf = text;
Rectangle ImgSize = new Rectangle(100, 100, 750, 1000);//'make the width and height whatever size you want the image to be
int checkPrint = 0;
MemoryStream memoryStream = new MemoryStream();
Bitmap bm = new Bitmap(ImgSize.Width, ImgSize.Height);
ImageCodecInfo encoderInfo = GetEncoderInfo("image/tiff");
EncoderParameters encoderParams = new EncoderParameters(2);
EncoderParameter parameter = new EncoderParameter(
System.Drawing.Imaging.Encoder.Compression, (long)EncoderValue.CompressionLZW);
encoderParams.Param[0] = parameter;
parameter = new EncoderParameter(System.Drawing.Imaging.Encoder.SaveFlag,
(long)EncoderValue.MultiFrame);
encoderParams.Param[1] = parameter;
EncoderParameters EncoderParams = new EncoderParameters(2);
EncoderParameter saveEncodeParam = new EncoderParameter(
System.Drawing.Imaging.Encoder.SaveFlag,
(long)EncoderValue.FrameDimensionPage);
EncoderParameter CompressionEncodeParam = new EncoderParameter(
System.Drawing.Imaging.Encoder.Compression, (long)EncoderValue.CompressionLZW);
EncoderParams.Param[0] = CompressionEncodeParam;
EncoderParams.Param[1] = saveEncodeParam;
using (bm)
{
using (Graphics grx = Graphics.FromImage(bm))
{
grx.Clear(Color.White);
RichTextBoxPrintCtrl richTextBoxPrintCtrl = new RichTextBoxPrintCtrl();
bool done = false;
int cnt = 0;
Image tiff;
checkPrint = richTextBoxPrintCtrl.Print(rtb, checkPrint, rtb.TextLength, grx, ImgSize);
if (checkPrint >= rtb.TextLength)
done = true;
bm.Save(memoryStream, System.Drawing.Imaging.ImageFormat.Tiff);
tiff = Image.FromStream(memoryStream);
tiff.Save(@"C:\Test\rtftomultitiff.tif", encoderInfo, encoderParams);
while (!done)
{
checkPrint = richTextBoxPrintCtrl.Print(rtb, checkPrint, rtb.TextLength, grx, ImgSize);
if (checkPrint >= rtb.TextLength)
done = true;
bm.Save(memoryStream, System.Drawing.Imaging.ImageFormat.Tiff);
tiff.SaveAdd(Image.FromStream(memoryStream), EncoderParams);
cnt += 1;
}
EncoderParameter SaveEncodeParam = new EncoderParameter(
System.Drawing.Imaging.Encoder.SaveFlag, (long)EncoderValue.Flush);
EncoderParams = new EncoderParameters(1);
EncoderParams.Param[0] = SaveEncodeParam;
tiff.SaveAdd(EncoderParams);
}
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
private static ImageCodecInfo GetEncoderInfo(String mimeType)
{
int j;
ImageCodecInfo[] encoders;
encoders = ImageCodecInfo.GetImageEncoders();
for (j = 0; j < encoders.Length; ++j)
{
if (encoders[j].MimeType == mimeType)
return encoders[j];
}
return null;
}
}
public class RichTextBoxPrintCtrl
{
//Convert the unit used by the .NET framework (1/100 inch)
//and the unit used by Win32 API calls (twips 1/1440 inch)
private const double anInch = 14.4;
[StructLayout(LayoutKind.Sequential)]
private struct RECT
{
public int Left;
public int Top;
public int Right;
public int Bottom;
}
[StructLayout(LayoutKind.Sequential)]
private struct CHARRANGE
{
public int cpMin; //First character of range (0 for start of doc)
public int cpMax; //Last character of range (-1 for end of doc)
}
[StructLayout(LayoutKind.Sequential)]
private struct FORMATRANGE
{
public IntPtr hdc; //Actual DC to draw on
public IntPtr hdcTarget; //Target DC for determining text formatting
public RECT rc; //Region of the DC to draw to (in twips)
public RECT rcPage; //Region of the whole DC (page size) (in twips)
public CHARRANGE chrg; //Range of text to draw (see earlier declaration)
}
private const int WM_USER = 0x0400;
private const int EM_FORMATRANGE = WM_USER + 57;
[DllImport("USER32.dll")]
private static extern IntPtr SendMessage(IntPtr hWnd, int msg, IntPtr wp, IntPtr lp);
// Render the contents of the RichTextBox for printing
// Return the last character printed + 1 (printing start from this point for next page)
// ByVal gr As Graphics, ByVal bounds As Rectangle
public int Print(Control rtb, int charFrom, int charTo, Graphics gr, Rectangle bounds)
{
//Calculate the area to render and print
RECT rectToPrint;
rectToPrint.Top = 1440;//(int)(bounds.Top * anInch);
rectToPrint.Bottom = 14400;// (int)(bounds.Bottom * anInch);
rectToPrint.Left = 1440; // (int)(bounds.Left * anInch);
rectToPrint.Right = 10800; // (int)(bounds.Right * anInch);
//Calculate the size of the page
RECT rectPage;
rectPage.Top = 0;// (int)(gr.ClipBounds.Top * anInch);
rectPage.Bottom = 15840;// (int)(gr.ClipBounds.Bottom * anInch);
rectPage.Left = 0;// (int)(gr.ClipBounds.Left * anInch);
rectPage.Right = 12240;// (int)(gr.ClipBounds.Right * anInch);
IntPtr hdc = gr.GetHdc();
FORMATRANGE fmtRange;
fmtRange.chrg.cpMax = charTo; //Indicate character from to character to
fmtRange.chrg.cpMin = charFrom;
fmtRange.hdc = hdc; //Use the same DC for measuring and rendering
fmtRange.hdcTarget = hdc; //Point at printer hDC
fmtRange.rc = rectToPrint; //Indicate the area on page to print
fmtRange.rcPage = rectPage; //Indicate size of page
IntPtr res = IntPtr.Zero;
IntPtr wparam = IntPtr.Zero;
wparam = new IntPtr(1);
//Get the pointer to the FORMATRANGE structure in memory
IntPtr lparam = IntPtr.Zero;
lparam = Marshal.AllocCoTaskMem(Marshal.SizeOf(fmtRange));
Marshal.StructureToPtr(fmtRange, lparam, false);
//Send the rendered data for printing
res = SendMessage(rtb.Handle, EM_FORMATRANGE, wparam, lparam);
//Free the block of memory allocated
Marshal.FreeCoTaskMem(lparam);
//Release the device context handle obtained by a previous call
gr.ReleaseHdc(hdc);
//Return last + 1 character printer
return res.ToInt32();
}
}
}