Bild aus HTML-Document extrahieren (Speichern unter...)
-
Hi Alle,
Ich habe mich ja in der letzten Zeit mal mit dem CppWebBrowser und IHTMLCollections usw. beschäftigt.
Die Bedienelemente und deren Eigenschaften aus einer HTML Seite zu extrahieren ist mir soweit ganz gut gelungen. Ich möchte jetzt über einen Dialog einzelne Bilder des HTML Documentes auf Festplatte saven, dazu habe ich folgendes probiert:
void __fastcall TfrmMain::SaveimageClick(TObject *Sender) { IHTMLImgElement *SelElement; TJPEGImage *JPEGImage = new TJPEGImage; TMemoryStream *mStream = new TMemoryStream(); if (SelImageItem) { try { SelElement = (IHTMLImgElement*)SelImageItem->Data; if (SelElement) { // das Image (SelElement) in den Stream kopieren mStream->Write(SelElement, 21208); // Image in JPEG laden JPEGImage->LoadFromStream(mStream); JPEGImage->SaveToFile("c:\\test.jpg"); // und saven } else MessageDlg("No element available.", mtInformation, TMsgDlgButtons() << mbOK, 0); } catch ( ... ) { MessageDlg("Error changing element.", mtError, TMsgDlgButtons() << mbOK, 0); } } delete JPEGImage; delete mStream; }Jo, leider ist es dann doch nicht so einfach wie gedacht. SelElement enthält nur eigenschaften des HTMLImages, hat aber keinen Zeiger auf die ImageResource an sich. Sowas muss es doch aber geben, da der Explorer ja auch mit "Speichern unter ..." Bilder speichern kann.
Wie kann ich sowas programmieren, mir fehlt die zündende Idee.

-
eigenschaften sollten genügen. Sie müssten auch den Dateinamen enthalten, mit dem kannst du sehr viel anfangen... z.B. nimm eine TIdHTTP-Komponente und lade das Bild dann herunter...
-
Ich gehe mal davon aus, dass F98 das selber wusste.
Der Punkt ist aber, das bereits geladene Bild nicht nochmal laden zu müssen.In Delphi gibt es offenbar die Möglichkeit, über die OleObject-Property da ranzukommen (letzte Beiträge), ich kann mich allerdings an eine ähnliche Diskussion hier erinnern, nach der dieses Vorgehen beim CppWebBrowser nicht möglich ist. Auf jeden Fall gibt es da schon mal kein OleObject.Document ...
-
Jo, CppWebBrowser hat kein OleObject->Document. Ich hatte mir gedacht es über IHTMLDocument zu versuchen, aber IHTMLDocument hat auch keine Images sondern nur eine Funktion get_images() die eine IHTMLElementCollection übergeben haben will. Wenn mann die durchwühlt kommt man zwar an die Imageeigenschaften (src, height ...) ran, aber nicht an die entsprechende Resource.
-
Ich habe jetzt folgendes gefunden:
IHTMLImgElement does not provide you access to either the locally stored
file or its actual data. For that, you will just have to find the image
file in the browser's cache manually and then copy the file to the new
location. You can use the IHTMLImgElement::src property to get the URL for
the image, and then use RetrieveUrlCacheEntryFile() to retreive the local
filename that it is cached as. Then you can use CopyFile() to copy it to
your desired destination folder.
-
noch folgende Frage: Wie komme ich an die URL heran, auf die ein Bild zeigt, wenn es folgendermaßen eingebaut ist:
<a href="http://www.heise.de"><img src="/icons/ho/heise.gif" alt="heise online"></a>Ich muß also das vorherige oder übergeordnete Objekt wiederfinden, welches dann wohl ein IHTMLAnchorElement ist, aber wie geht das?
Ich finde das Bild, auf das geklickt wurde, folgendermaßen heraus:
AnsiString TAcDocHandler::getImageUnderMouse(POINT mousePos, AnsiString* imgLinkTo) { AnsiString url = ""; TCppWebBrowser *wbMain = browser; IHTMLDocument2 *pDoc = NULL; IHTMLElement *pElement = NULL; IHTMLImgElement *pImage = NULL; bool blUrl = false; try { if(wbMain->Document == NULL) return ""; WideString wURL; WideString wImgUrl; POINT p = mousePos; if(SUCCEEDED(wbMain->Document->QueryInterface(IID_IHTMLDocument2,(LPVOID*)&pDoc))) { if(pDoc == NULL) return ""; //GetCursorPos(&p); p = wbMain->ScreenToClient(p); if(SUCCEEDED(pDoc->elementFromPoint(p.x, p.y, &pElement))) { if(pElement == NULL) return ""; if(SUCCEEDED(pElement->QueryInterface(IID_IHTMLImgElement,(LPVOID*)&pImage))) { if(pImage == NULL) return ""; if(SUCCEEDED(pImage->get_src(&wURL))) { blUrl = true; url = AnsiString(wURL); } } } } } __finally { if(!blUrl) url = ""; if(pDoc != NULL) pDoc->Release(); if(pElement != NULL) pElement->Release(); if(pImage != NULL) pImage->Release(); return url; } }Aber wie bekomme ich jetzt das IHTMLAnchorElement heraus, in diesem Fall "http://www.heise.de"?
-
Ich habe mir extrahieren des Seiteninhalts folgende Funktionen umgesetzt:
// Seiteninhalt für jedes Frame zerflücken bool __fastcall TfrmMain::GetHTMLElements() { IHTMLDocument2 *HTMLDocument = NULL; LONG ilFramesCount = 0; bool bretVal = true; try { if (WebBrowserWin->Document) { sbStatus->SimpleText = "All HTML data from "+cbURL->Text+" received"; lvFormElements->Items->Clear(); lvImageElements->Items->Clear(); lvInputElements->Items->Clear(); lvURL->Items->Clear(); // Falls eine Seite geladen: if (SUCCEEDED(WebBrowserWin->Document->QueryInterface(IID_IHTMLDocument2, (LPVOID*)&HTMLDocument))) { if (HTMLDocument != NULL) { IHTMLFramesCollection2 *pFrames = NULL; if (SUCCEEDED(HTMLDocument->get_frames(&pFrames))) { // Anzahl der Frames bestimmen: pFrames->get_length(&ilFramesCount); // wenn nur ein Frame if (ilFramesCount < 2) GetFrameContent(HTMLDocument); else { VARIANT vFrame; VariantInit(&vFrame); vFrame.vt = VT_UINT; vFrame.lVal = 0; VARIANT vRet; VariantInit(&vRet); vRet.vt = VT_UINT; vRet.lVal = 0; // ansonsten für jedes Frame einzeln: for (LONG ilFrameIndex = 0; ilFrameIndex < ilFramesCount; ilFrameIndex++) { vFrame.lVal = ilFrameIndex; if (SUCCEEDED(pFrames->item(&vFrame, &vRet))) { IHTMLWindow2 *pWindow = NULL; if (SUCCEEDED(vRet.pdispVal->QueryInterface(IID_IHTMLWindow2, (LPVOID*)&pWindow))) { IHTMLDocument2 *pDoc = NULL; if (SUCCEEDED(pWindow->get_document(&pDoc))) { GetFrameContent(pDoc); pDoc->Release(); } pWindow->Release(); } } } VariantClear(&vFrame); VariantClear(&vRet); } pFrames->Release(); } HTMLDocument->Release(); } } tbRescan->Enabled = true; } } catch ( Exception &E ) { MessageDlg(E.Message, mtError, TMsgDlgButtons() << mbOK, 0); bretVal = false; } return bretVal; } bool __fastcall TfrmMain::GetFrameContent(IHTMLDocument2 *HTMLDocument) { IHTMLElementCollection *pAll = NULL; TListItem *ListItem; bool bretVal = true; try { if (HTMLDocument != NULL) { if (SUCCEEDED(HTMLDocument->get_all(&pAll)) && pAll) { long iColLengh; pAll->get_length(&iColLengh); for (long i=0; i<iColLengh; i++) { VARIANT vIndex; VariantInit(&vIndex); vIndex.vt = VT_UINT; vIndex.lVal = i; IDispatch *pDisp = NULL; // erstmal ein Item holen if (SUCCEEDED(pAll->item(vIndex, vIndex, &pDisp)) && pDisp) { IHTMLInputElement *pInput = NULL; IHTMLFormElement *pForm = NULL; IHTMLImgElement *pImg = NULL; IHTMLAnchorElement *pAnchor = NULL; WideString wsElementName; WideString wsElementValue; WideString wsElementType; WideString wsElementForm; WideString wsElementSize; WideString wsElementSrc; WideString wsElementAction; WideString wsElementHREF; // ist es ein Inputelement (Edit)? if (SUCCEEDED(pDisp->QueryInterface(IID_IHTMLInputElement, (LPVOID*)&pInput)) && pInput) { IHTMLFormElement *pTempForm = NULL; pInput->get_name(&wsElementName); pInput->get_value(&wsElementValue); pInput->get_type(&wsElementType); pInput->get_form(&pTempForm); if (pTempForm) pTempForm->get_name(&wsElementForm); ListItem = lvInputElements->Items->Add(); ListItem->Caption = wsElementName; ListItem->SubItems->Add(wsElementForm); ListItem->SubItems->Add(wsElementType); ListItem->SubItems->Add(wsElementValue); ListItem->Data = pInput; } else { // oder ein Formularelement (Button) ? if (SUCCEEDED(pDisp->QueryInterface(IID_IHTMLFormElement, (LPVOID*)&pForm)) && pForm) { AnsiString sTempName; AnsiString sTempAction; pForm->get_name(&wsElementName); pForm->get_action(&wsElementAction); sTempName = wsElementName; sTempAction = wsElementAction; if ((!sTempName.IsEmpty()) && (!sTempAction.IsEmpty())) { ListItem = lvFormElements->Items->Add(); ListItem->Caption = wsElementName; ListItem->SubItems->Add(wsElementAction); ListItem->Data = pForm; } } else { // ein Image? if (SUCCEEDED(pDisp->QueryInterface(IID_IHTMLImgElement, (LPVOID*)&pImg)) && pImg) { pImg->get_name(&wsElementName); pImg->get_src(&wsElementSrc); pImg->get_fileSize(&wsElementSize); AnsiString sTempName = wsElementName; if (sTempName.IsEmpty()) sTempName = "empty"; ListItem = lvImageElements->Items->Add(); ListItem->Caption = sTempName; ListItem->SubItems->Add(wsElementSrc); ListItem->SubItems->Add(wsElementSize); ListItem->Data = pImg; } else { // oder eine URL? if (SUCCEEDED(pDisp->QueryInterface(IID_IHTMLAnchorElement, (LPVOID*)&pAnchor))) { if (SUCCEEDED(pAnchor->get_href(&wsElementHREF))) { ListItem = lvURL->Items->Add(); ListItem->Caption = wsElementHREF; ListItem->Data = pAnchor; } } } } } pDisp->Release(); } VariantClear(&vIndex); } pAll->Release(); } } } catch ( Exception &E ) { MessageDlg(E.Message, mtError, TMsgDlgButtons() << mbOK, 0); bretVal = false; } return bretVal; }