Saltar al contenido

Agregar imágenes mediante programación a un documento RTF

Este artículo ha sido evaluado por especialistas así garantizamos la veracidad de nuestra esta noticia.

prueba estos enlaces

  • Especificación de formato de texto enriquecido (RTF), versión 1.6
  • ¿Cómo puedo insertar una imagen en un RichTextBox?
  • Insertar imagen en documento rtf

debes cambiar “picwgoa” a “picwgoal” y “pichgoa” a “pichgoal”

string mpic = @"pictpngblippicw" + 
    img.Width.ToString() + @"pich" + img.Height.ToString() +
    @"picwgoal" + width.ToString() + @"pichgoal" + height.ToString() + 
    @"bin " + str + "";

Aquí tienes una lista de los formatos de imagen admitidos.

emfblip      Source of the picture is an EMF (enhanced metafile).
pngblip      Source of the picture is a PNG.
jpegblip     Source of the picture is a JPEG.
shppict      Specifies a Word 97-2000 picture. This is a destination control word.
nonshppict   Specifies that Word 97-2000 has written a {pict destination that it will not read on input. This keyword is for compatibility with other readers.
macpict      Source of the picture is QuickDraw.
pmmetafileN  Source of the picture is an OS/2 metafile. The N argument identifies the metafile type. The N values are described in the pmmetafile table below.
wmetafileN   Source of the picture is a Windows metafile. The N argument identifies the metafile type (the default is 1).
dibitmapN    Source of the picture is a Windows device-independent bitmap. The N argument identifies the bitmap type (must equal 0).The information to be included in RTF from a Windows device-independent bitmap is the concatenation of the BITMAPINFO structure followed by the actual pixel data.    
wbitmapN     Source of the picture is a Windows device-dependent bitmap. The N argument identifies the bitmap type (must equal 0).The information to be included in RTF from a Windows device-dependent bitmap is the result of the GetBitmapBits function.

Pasé un día o dos buscando respuestas en Google para esto. Tidbits reunidos de todo stackoverflow y otras fuentes. Alimenta esto con una imagen, devolverá el string debe agregar a su extensión richtextbox.rtf. El ancho de la imagen cambia y debe calcularse, se da la fórmula.

    // RTF Image Format
    // {pictwmetafile8picw[A]pich[B]picwgoal[C]pichgoal[D]
    //  
    // A    = (Image Width in Pixels / Graphics.DpiX) * 2540 
    //  
    // B    = (Image Height in Pixels / Graphics.DpiX) * 2540 
    //  
    // C    = (Image Width in Pixels / Graphics.DpiX) * 1440 
    //  
    // D    = (Image Height in Pixels / Graphics.DpiX) * 1440 

    [Flags]
    enum EmfToWmfBitsFlags
    
        EmfToWmfBitsFlagsDefault = 0x00000000,
        EmfToWmfBitsFlagsEmbedEmf = 0x00000001,
        EmfToWmfBitsFlagsIncludePlaceable = 0x00000002,
        EmfToWmfBitsFlagsNoXORClip = 0x00000004
    

    const int MM_ISOTROPIC = 7;
    const int MM_ANISOTROPIC = 8;

    [DllImport("gdiplus.dll")]
    private static extern uint GdipEmfToWmfBits(IntPtr _hEmf, uint _bufferSize,
        byte[] _buffer, int _mappingMode, EmfToWmfBitsFlags _flags);
    [DllImport("gdi32.dll")]
    private static extern IntPtr SetMetaFileBitsEx(uint _bufferSize,
        byte[] _buffer);
    [DllImport("gdi32.dll")]
    private static extern IntPtr CopyMetaFile(IntPtr hWmf,
        string filename);
    [DllImport("gdi32.dll")]
    private static extern bool DeleteMetaFile(IntPtr hWmf);
    [DllImport("gdi32.dll")]
    private static extern bool DeleteEnhMetaFile(IntPtr hEmf);

        public static string GetEmbedImageString(Bitmap image)
        
                Metafile metafile = null;
                float dpiX; float dpiY;

                using (Graphics g = Graphics.FromImage (image)) 
                
                    IntPtr hDC = g.GetHdc ();
                    metafile = new Metafile (hDC, EmfType.EmfOnly);
                    g.ReleaseHdc (hDC);
                

                using (Graphics g = Graphics.FromImage (metafile)) 
                
                    g.DrawImage (image, 0, 0);
            dpiX = g.DpiX;
            dpiY = g.DpiY;
                

                IntPtr _hEmf = metafile.GetHenhmetafile ();
                uint _bufferSize = GdipEmfToWmfBits (_hEmf, 0, null, MM_ANISOTROPIC,
                EmfToWmfBitsFlags.EmfToWmfBitsFlagsDefault);
                byte[] _buffer = new byte[_bufferSize];
                GdipEmfToWmfBits (_hEmf, _bufferSize, _buffer, MM_ANISOTROPIC,
                                            EmfToWmfBitsFlags.EmfToWmfBitsFlagsDefault);
                IntPtr hmf = SetMetaFileBitsEx (_bufferSize, _buffer);
                string tempfile = Path.GetTempFileName ();
                CopyMetaFile (hmf, tempfile);
                DeleteMetaFile (hmf);
                DeleteEnhMetaFile (_hEmf);

                var stream = new MemoryStream ();
                byte[] data = File.ReadAllBytes (tempfile);
                //File.Delete (tempfile);
                int count = data.Length;
                stream.Write (data, 0, count);

                string proto = @"rtf1pictwmetafile8picw" + (int)( ( (float)image.Width / dpiX ) * 2540 )
                                  + @"pich" + (int)( ( (float)image.Height / dpiY ) * 2540 )
                                  + @"picwgoal" + (int)( ( (float)image.Width / dpiX ) * 1440 )
                                  + @"pichgoal" + (int)( ( (float)image.Height / dpiY ) * 1440 )
                                  + " " 
                      + BitConverter.ToString(stream.ToArray()).Replace("-", "")
                                  + "";                   
                return proto;
        

Los visitantes posteriores a esta página (como yo hace unos días) pueden encontrar el siguiente enlace útil: convierte una imagen en WMF con .NET

Uno encontrará que WordPad ignora cualquier imagen que no esté almacenada en el formato de metaarchivo de Windows adecuado. Por lo tanto, el ejemplo anterior en esta página no se mostrará en absoluto (aunque funciona bien en OpenOffice y Word). El formato que admitirá WordPad es:

/ pict / wmetafile8 / picw[width]/ pich[height]/ picwgoal[scaledwidth]/ pichgoal[scaledheight] [image-as-string-of-byte-hex-values] (con términos entre corchetes reemplazados por los datos apropiados).

Puede obtener los ‘datos adecuados’ siguiendo los procedimientos del enlace anterior. Para aquellos con Python que buscan una solución, aquí está el comienzo de una (creo que quedan algunos problemas de dpi / escala). Esto requiere PIL(o Almohada), ctipos, y clr (Python .NET). Utilice PIL / Pillow y abra la imagen primero. Aquí lo tengo abierto como “canv”:

from ctypes import *
import clr
clr.AddReference("System.IO")
clr.AddReference("System.Drawing")
from System import IntPtr
from System.Drawing import SolidBrush
from System.Drawing import Color
from System.Drawing import Imaging
from System.Drawing import Graphics
from System.IO import FileStream
from System.IO import FileMode
from System.IO import MemoryStream
from System.IO import File

def byte_to_hex(bytefile):
  acc = ''
  b = bytefile.read(1)
  while b:
    acc+=("%02X" % ord(b))
    b = bytefile.read(1)
  return acc.strip()

#... in here is some code where 'canv' is created as the PIL image object, and
#...   'template' is defined as a string with placeholders for picw, pich, 
#...   picwgoal, pichgoal, and the image data


mfstream     = MemoryStream()
offscrDC     = Graphics.FromHwndInternal(IntPtr.Zero)
imgptr       = offscrDC.GetHdc()
mfile        = Imaging.Metafile(mfstream, imgptr, Imaging.EmfType.EmfOnly)
gfx          = Graphics.FromImage(mfile)
width,height = canv.size
pixels       = canv.load()
for x in range(width):
  for y in range(height):
    _r,_g,_b = pixels[x, y]
    c     = Color.FromArgb(_r, _g, _b)
    brush = SolidBrush(c)
    gfx.FillRectangle(brush, x, y, 1, 1)
gfx.Dispose()
offscrDC.ReleaseHdc()
_hEmf            = mfile.GetHenhmetafile()
GdipEmfToWmfBits = windll.gdiplus.GdipEmfToWmfBits
_bufferSize      = GdipEmfToWmfBits(
                      int(str(_hEmf)),
                      c_uint(0),
                      None,
                      c_int(8),           # MM_ANISOTROPIC
                      c_uint(0x00000000)) # Default flags
_buffer = c_int * _bufferSize
_buffer = _buffer(*[0 for x in range(_bufferSize)])
GdipEmfToWmfBits( int(str(_hEmf)),
                  c_uint(_bufferSize),
                  _buffer,
                  c_int(8),            # MM_ANISOTROPIC
                  c_uint(0x00000000) ) # Default flags
hmf = windll.gdi32.SetMetaFileBitsEx(c_uint(_bufferSize), _buffer)
windll.gdi32.CopyMetaFileA(int(str(hmf)), "temp.wmf")
windll.gdi32.DeleteMetaFile(int(str(hmf)))
windll.gdi32.DeleteEnhMetaFile(int(str(_hEmf)))
mfstream.Close()

imgstr = open("temp.wmf", 'rb')
imgstr = byte_to_hex(imgstr)
with open('script-out.rtf','wb') as outf:
  template = template % (str(_cx),str(_cy),str(15*_cx),str(15*_cy),imgstr)
  outf.write(template)

Reseñas y calificaciones del artículo

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)


Tags :

Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *