Xpoint
   [напомнить пароль]

Как сохранить картинку?

Метки: [без меток]
2008-08-09 00:52:02 [обр] Андрей[досье]

Помогите начинающему в новой среде (javascript под firefox).
Нужно по райтклику сохранить картинку в файл. Нашел несколько примеров похожих, но ни один почему-то не работает либо неясно как добиться того, что нужно.
Выходной файл например так получаю:
var file = Components.classes["@mozilla.org/file/local;1"].createInstance(Components.interfaces.nsILocalFile);
file.initWithPath("C:\\file1.jpg");

WebBrowser получаю так:
var wbp = Components.classes['@mozilla.org/embedding/browser/nsWebBrowserPersist;1']
                    .createInstance(Components.interfaces.nsIWebBrowserPersist);

wbp.saveDocument работает, если в качестве сорса задать content.document, сохраняет хтмл всей страницы.
Но мне нужна картинка, на которую кликнули. Ее урл получаю так:
  var imgSrc = gContextMenu.target.getAttribute("src");
Вроде бы получается правильная урл. Но как "попросить" WebBrowser сохранить ее - не знаю.
Пробовал безуспешно:
  wbp.saveURL(imgSrc, file, null, null, null, null);
  wbp.saveDocument(gContextMenu.target, file, null, null, null, null);
  wbp.saveURI(imgSrc, file, null, null, null, null);

Либо в другом примере поток не открывается:
  var ioserv = Components.classes["@mozilla.org/network/io-service;1"].
      getService(Components.interfaces.nsIIOService);
  var channel = ioserv.newChannel(imgSrc, 0, null);
  var stream = channel.open();
Но и все-равно неясно, что дальше делать со стримом, как его перенаправить в файл.
Видимо надо создать выходной поток (nsIFileOutputStream) в файл и как-то состыковать его с входным потоком, но это уже другая проблема.

спустя 10 дней [обр] Владимир Палант(434/4445)[досье]

Для начала, вот документация этого интерфейса: http://www.xulplanet.com/refer......aces/nsIWebBrowserPersist.html. Зачем гадать?

То есть вам нужен метод saveURI. Параметром у него nsIURI, его вы получите так:

  var ioserv = Components.classes["@mozilla.org/network/io-service;1"].
      getService(Components.interfaces.nsIIOService);
  var uri = ioserv.newURI(imgSrc, null, gContextMenu.target.ownerDocument.URL);

Последний параметр нужен на тот случай, если в картинке адрес указан относительный. Дальше пишем:

  wbp.saveURI(uri, null, null, null, null, file);

На самом деле не мешало бы указать referrer и cacheKey — но работать должно и без этого.

спустя 3 дня [обр] Андрей[досье]
Спасибо за ответ!
Но уже сам разобрался, все заработало.
спустя 7 часов [обр] Андрей[досье]
Кстати, с относительными адресами, если использовать:
  var uri = ioserv.newURI(imgSrc, null, gContextMenu.target.ownerDocument.URI);
(на конце URI, с URL не работает вообще), то выдает ошибку.
Если же я вручную делаю конкатенацию
  gContextMenu.target.ownerDocument.URL + imgSrc, то вроде бы получается правильный URL и все работает.
Понятно, что это не совсем правильно, но как сделать и правильно, и чтоб работало?
спустя 3 дня [обр] Владимир Палант(434/4445)[досье]
Я ведь не ясновидящий. То, что у вас URI вместо URL написано — это вижу. В остальном придется все-таки привести текст ошибки...
спустя 1 день 17 часов [обр] Андрей[досье]
Когда я ставил там УРЛ - просто затыкалось (то есть выподлнение скрипта в этом месте прекращалось). Когда поставил УРИ - для абсолютного пути стало возвращать его же, для относительного - ошибку. Очень скоро однако выяснилось, что путь тупиковый, для относительных путей так много разновидностей, что построить правильный УРЛ картинки нереально. Путем долгих экспериментов было найдено решение
   var uri = gContextMenu.target.QueryInterface(Ci.nsIImageLoadingContent).currentURI;
спустя 1 месяц 7 дней [обр] Alex[досье]

>>Когда я ставил там УРЛ - просто затыкалось (то есть выподлнение скрипта в этом месте прекращалось

Значит вываливалось исключение, которое нужно ловить try { } catch(e) { }

Powered by POEM™ Engine Copyright © 2002-2005