Link to home
Start Free TrialLog in
Avatar of Anthar
Anthar

asked on

Extracting an image from a richtextbox, Part 2

Okay, new snag.

This is related to a previous question:
https://www.experts-exchange.com/questions/21085056/Extracting-an-image-from-a-richtextbox-into-an-image-object.html

The previous question was answered with a good solution, but I have run into one problem with the code.  I need to not use the Clipboard.  Here's a code sample:

Dim n As Integer
        Dim text As String

        For n = 0 To RichTextBox1.TextLength

            'select piece by piece
            RichTextBox1.Select(n, 1)  

            'Check is this an Object
            If RichTextBox1.SelectionType = RichTextBoxSelectionTypes.Object Then
                'When found, copy this to Clipboard!
                RichTextBox1.Copy()
            End If
        Next

Is there a way to extract the object straight from the richtextbox without using the clipboard to copy?

Thanks for any help you can give.
Avatar of Howard Cantrell
Howard Cantrell
Flag of United States of America image

Avatar of Anthar
Anthar

ASKER

There are some problems with that solution.  The first being that it uses the clipboard.  

I think I should explain what I'm doing in a little more detail.

1. The end user is looking at an ASP.NET page, from this page they upload an RTF file.  
2. I then take that file and pass the rtf code to a web service.
3. The web service loads a richtextbox into memory and sets the rtf property to the rtf that the end user uploaded
4. The web service loops through the contents of the richtextbox looking for images

All of that works fine.

The problem arises when the web service finds an image.  The code snippet I listed above might be fine if this were a client side app, but I can't use the clipboard on my web service server because conflicts will happen when more than one file is being processed and both will need access to the clipboard for their images.  The fact that the processing occurs on the server is also why any solution that involves capturing the image to a picturebox on the client side won't work.

Any ideas?
Ok heres something else that is interesting......

http://www.inner-smile.com/dl_res.htm
Avatar of Anthar

ASKER

Thanks for trying again.  If I could get the source code for that it would probably be helpful.  Unfortunately, it scans for images in files on the hard drive, I didn't see any mention of a programming interface.  I need to avoid saving the files to the hard drive, because we don't want to deal with write permissions.  Both the images and the text of the file are being prepped for database storage.

Hello Anthar...  here am I again.. I am sorry my solution the other day did not help you... I will give it (again) a try ;-)

I have the source code still on my harddisk... I am looking forward to send you (again) a solution...
Avatar of Anthar

ASKER

Thanks, Daniël.  I was hoping you might see this and have some idea.  Don't get me wrong, the solution you gave me before was very helpful, I just hadn't thought through the clipboard issue.

Anthar,... again i've been trying real hard to get it working. I tried already much (like creating a own made clipboard, with IBandObject variable etc.., no succes).

But I just got this idea: As executing the Copy&Paste (to/from Clipboard) on the serverside causes problems you might want to think about code (javascripts?) that executes on clientside. I don't (yet) know what is possible.. but you might think about this...

The other idea is to work with threading (I have no experience on this subject on windows.form or asp.net) on serverside,... you put all the files in a line to be processed... And do scan then one after the other...

After all,.. this is more complicated than you would think :-)
Avatar of Anthar

ASKER

I appreciate your help, Daniël.  

A client side copy and paste isn't an option because there is no client side.  They are submitting an already formatted and saved rtf file.  

As far as queueing the clipboard operations go, I suppose I could give that a try, but then there are a few other issues.  Namely, I've been having trouble accessing the clipboard from the WebService.  It doesn't error on the Copy method, but when I try to actually get the data it says there's nothing there.  That's not the main reason I'm trying to get around the clipboard, but it is certainly a consideration.

Indeed,... I realized later that the file is being uploaded...

This brings me to another idea, this should be a nice try:

Download the Office XP PIA: https://www.experts-exchange.com/questions/21100155/Compiling-with-strong-key-name.html#11846630

> Include the interop.word.dll into your project
   
    (I don't know if this works on the server... You might need to ask you ISP/hosting Company/ or yourself ;-)  to install this .dll in the MMC)

> Then define a new application and document and open this uploaded RTF file,

   code should look something like this:

        Dim wordApp As Microsoft.Office.Interop.Word.Application = New Microsoft.Office.Interop.Word.Application
        Dim doc As Microsoft.Office.Interop.Word.Document = wordApp.Documents.Open(Path_to_rtf_file, True)

> then you will be able to save this with code like this.

        doc.SaveAs(Your_html_file, Microsoft.Office.Interop.Word.WdSaveFormat.wdFormatHTML)
        doc.Close(False)
        System.Runtime.InteropServices.Marshal.ReleaseComObject(doc)

---------------------------

This might sound scary.. but try it yourself.. Open an example RTF into Word (I used office XP) and Save this file again as webpage... The Images from the rtf should be in the folder:

    ...\FilenameRTF_files\

And you know what's nice about this?... the folder contains standard a file "files.xml" in wich you can (of course) find the names of the files with images...


For now I cannot give you a better solution... This is my best bet at this moment ;-)

Here I have working code for a windows Form app (Form with 1 Button)

-----------------------------------------------------------------------------------------------------------------------------------
    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

        Dim BestandsNaam As String
        Dim wordApp As New Microsoft.Office.Interop.Word.Application
        Dim doc As New Microsoft.Office.Interop.Word.Document

        If LoadParameterFile.ShowDialog() = DialogResult.OK Then
            BestandsNaam = LoadParameterFile.FileName
            doc = wordApp.Documents.Open(BestandsNaam, False)
        End If

        If SaveParameterFile.ShowDialog() = DialogResult.OK Then
            BestandsNaam = SaveParameterFile.FileName
            doc.SaveAs(BestandsNaam, Microsoft.Office.Interop.Word.WdSaveFormat.wdFormatHTML)
            doc.Close(False)
            wordApp.Quit()
        End If

        System.Runtime.InteropServices.Marshal.ReleaseComObject(doc)

    End Sub
-----------------------------------------------------------------------------------------------------------------------------------

As posted earlier (but I made a mistake in the hyperlink).. to be able to run this you will need the proper Reference (Microsoft.Office.Interop.Word.dll). Download from:
            http://www.microsoft.com/downloads/details.aspx?familyid=c41bd61e-3060-4f71-a6b4-01feba508e52&displaylang=en

---

Notes:

> I know (if this works on an ASP.Net Server) you have to deal with write permissions. But that should not be the biggest problem since you also must need a location to store your uploaded RTF file...

> If I am right... you are able to do more settings on the saving procedure. e.g. you can force the Word-dll to use PNG....
Avatar of Anthar

ASKER

Actually, I'm not saving the file directly to the harddrive.  I'm processing the file in memory and then inserting the text and images into seperate database fields.  I'll do it as a last resort, but I'd like to avoid writing files to the harddrive if at all possible, in part because we use a load balanced server cluster for a web sites, having to write to a common share (while not impossible) would complicatre things.  Using Word seems like a good idea, and I looked into it, but if I use that method, there's no way to get around writing to the hard drive.  I'd really like to find a way to get the images directly from the rtf.
Okay.. I'll keep trying...
holy beep... I just did it! Freaking amazing... (I am going crazy right now). I just suceed to save this picture from a richtextbox... I was first reversing some c# code that made it possible to input images in Richtextbox... But I had to get MSDN for other functions

I have to work out some more things, like risizing etc... I see now my test pic a little big... I also have to test all 8 modes the Windows Metafile can be stored in by the RTF-program our users use...

Technical: I used the image data (rtfsource) for the bitmap, cut the hexadecimal code off and convert it into a binary buffer, then I read it with some functions from GDI32.dll... save it to metafile format and show it onto the picturebox.

I cant tell how much more time..








ASKER CERTIFIED SOLUTION
Avatar of Daniellus83
Daniellus83
Flag of Netherlands image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of Anthar

ASKER

That's so great, I can't believe you did it!  Wow, it doesn't even look that bad, using this code I might not even have to load the richtextbox into memory.  Thank you so much, Daniël.  I'm going to plug it in to my Web Service, I'll let you know how it goes.  Thanks, again.
I couldnt believe it either... I was testing it, and suddenly the program printed the image HUGE on my picturebox... (I was dancing around ;-) ). You sure can imagine after 3 days of trail & error....

But I wanted to add this: I couldn't test the code throughly since its such a big project; but the following assumptions does the code make:

> The picture is always (!) stored as wmetafile type (windows metafile) into the rtf. If not, this pic is not recognised... ( but all the pics I tried went well!)
    If this is a problem (I don't expect it to be), we have to work all other formats out..... (I don't want that!)
> The picture's dimensions are >=1000 and <= 9999. This can be adjusted, but most pics will fall into that range.

And further; the code loops through all RTF and puts all images found (& recognised) into a metafile-array. I added and NumericUpDown to my form to check them all. You might first wanna create your own windows.Forms version so you can see how it works. At least it doesn't use clipboard but an private string and byte-array to store those ones and zeros...

Sweet dreams, Daniël
Avatar of Anthar

ASKER

Man, you are a life saver.  That code worked beautifully, in both the form I created to test, and in the Web Service I have to use for the app.

I'm pretty sure that the images will always be stored as metafiles, so that shouldn't be a problem.

I did fix the 1000 to 9999 assumption, though, just to be safe.  I thought you might like to see the code, nothing too complicated:

Dim sXnorm As String  'Declare at the beginning of the function
Dim iNextNumber As Integer
Dim x

'< Code Omitted >

ElseIf Properties.Substring(m, 5) = "\picw" And Not Properties.Substring(m, 9) = "\picwgoal" Then
  'Warning: I assume here that the number is 4 digits long (xxxx),.. this goes wrong with 1,2,3,,5,6.. digits!!
  'xnorm = Val(Properties.Substring(m + 5, 4))    
  'The code below fixes the 4 digit assumption
  iNextNumber = 5
  'Initialize the string...I had done this on declaration at the start of the function, but I quickly found that it had to be initialized in the loop if there is more than one image
  sXnorm = ""
  x = Properties.Substring(m + iNextNumber, 1)
  Do While IsNumeric(x)
    sXnorm = sXnorm & Properties.Substring(m + iNextNumber, 1)
    iNextNumber += 1
    x = Properties.Substring(m + iNextNumber, 1)
  Loop
  xnorm = Val(sXnorm)

Just repeat for each of the 4 xnorm, ynorm, xgoal, ygoal.

Like I said, nothing special.

Thanks for all your help Daniël, you've been a HUGE help.
Nice! And I want to tremendously thank you for the feedback,... Thats always something pleasent to read back ;-)

I knew this extra code wouldn't be very difficult, but I had already written the code for multiple recognision and storage to metafile-array, so I left it to you. Sounds lazy, but now you altered the code, I am convinced you gave it a good look ;-) (Just kiddin'...) Now it is really complete! Thanks!

I might one day need this myself for my own website... its really a easy way (with asp.net) to store uploaded text with pics...

Good luck so far needed with you project, maybe we meet again on a "Extracting an image from a richtextbox, Part 3" ... :~)

Daniël Trommel