101

Re: AHK: Объединить кусочки картинок в одно целое

А вы пока найдите другие книги с такой же структурой и проверьте, все ли они не хотят загружаться.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

102

Re: AHK: Объединить кусочки картинок в одно целое

Не захотят, так как там через другой вьюер загружается - openseadragon.
У него данные в dzi прописываются.

                for (var file in seadragon.files) {
                    tileSources.push(seadragon.iipsrvURL + '/fcgi-bin/iipsrv.fcgi?DeepZoom=' + seadragon.filesPath + '/' + seadragon.files[file] + '.dzi');

Я не понимаю одного, почему эти библиотеки не дают скачать?
Ведь всё-равно кому надо выкачает.

103

Re: AHK: Объединить кусочки картинок в одно целое

Если знаешь, как с ними обходиться, напиши, мне пока лень разбираться.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

104

Re: AHK: Объединить кусочки картинок в одно целое

Не, не знаю, я просто посмотрел что подгружается.
Мне тоже лень.

105

Re: AHK: Объединить кусочки картинок в одно целое

Собственно, скачиваются все нужные файлы, просто количество неправильно определяется. Если поделить указанные в json ширину и высоту на два, все собирается правильно. Теперь если кто-то точно мне скажет, как наверняка отличить первый вариант от второго по исходному коду, внесу поправки.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

106 (изменено: teadrinker, 2020-03-06 15:54:25)

Re: AHK: Объединить кусочки картинок в одно целое

Нет, не так всё просто оказалось. Здесь тоже есть этот самый seadragon-viewer, однако обычным способом размер определяется и скачивается правильно. Значит, неважно, какой там вьювер, tiff-файлы с одинаковой нумерацией есть в любом случае. Вопрос, как правильно определить их количество в ряду и соответственно общее количество.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

107 (изменено: teadrinker, 2020-03-06 16:39:43)

Re: AHK: Объединить кусочки картинок в одно целое

Вроде понял:

#NoEnv
SetBatchLines, -1
CoordMode, ToolTip
PrLibDownload(362052, 11)  ; 377452
MsgBox, Completed!

PrLibDownload(item, page, zoom := "max") {
   if !GetItemInfo(item, page, zoom, width, height, file, id1, id2)
      Return
   
   if !GetChunkDimension(id1, id2, file, zoom, chunkWidth, chunkHeight)
      Return
   
   BuildImg(id1, id2, file, zoom, width, height, chunkWidth, chunkHeight, item . "-" . page . ".tif")
}

GetItemInfo(item, page, ByRef zoom, ByRef width, ByRef height, ByRef file, ByRef id1, ByRef id2) {
   ToolTip, Getting item info ..., 2, 2, 1
   Loop 1 {
      if !html := GetHtml("https://www.prlib.ru/item/" . item) {
         error := "Failed to load html"
         break
      }
      if !RegExMatch(html, "i)public\\/([a-f\d]{8}(?:-[a-f\d]{4}){3}-[a-f\d]{12})\\/(\d+)", id) {
         error := "Failed to get IDs"
         break
      }
      if !metadataJson := GetHtml("https://content.prlib.ru/metadata/public/" . id1 . "/" . id2 . "/" . id1 . ".json") {
         error := "Failed to get metadata"
         break
      }
      try Json := GetJS().eval("(" . metadataJson . ")")
      catch {
         error := "Bad Json data"
         break
      }
      maxPage := Json["pgs"].length
      if (page > maxPage) {
         MsgBox, There is no page %page%, max page number is %maxPage%
         Return
      }
      try maxZoom := Json.max_zoom
      catch {
         error := "Failed to get max_zoom value: unknown json format"
         break
      }
      (zoom = "max" && zoom := maxZoom)
      if (maxZoom < zoom) {
         error := "Zoom " . zoom . " is not supported. Max zoom is " . maxZoom
         break
      }
      Page := Json["pgs"][page - 1]
      Dim := Page["d"][zoom]
      try width := Dim.w
      catch {
         error := "Failed to get image width: unknown json format"
         break
      }
      try height := Dim.h
      catch {
         error := "Failed to get image height: unknown json format"
         break
      }
      try file := Page.f
      catch {
         error := "Failed to get image fileName: unknown json format"
         break
      }
      try m := Page.m
      catch {
         error := "Failed to get m-value: unknown json format"
         break
      }
      zoom += m - maxZoom
   }
   ToolTip,,,, 1
   if !error
      Return true
   else
      MsgBox, % error
}

GetChunkDimension(id1, id2, file, zoom, ByRef chunkWidth, ByRef chunkHeight) {
   static preUrl := "https://content.prlib.ru/fcgi-bin/iipsrv.fcgi?FIF=/var/data/scans/public/"
   if !hBitmap := GetHBitmapFromImageURL(preUrl . id1 . "/" . id2 . "/" . file . "&JTL=" . zoom . ",0") {
      MsgBox, Failed to get bitmap from url
      Return
   }
   VarSetCapacity(BITMAP, sz := 4*4 + A_PtrSize*2, 0)
   DllCall("GetObject", "Ptr", hBitmap, "Int", sz, "Ptr", &BITMAP)
   DllCall("DeleteObject", "Ptr", hBitmap)
   chunkWidth  := NumGet(BITMAP, 4, "UInt")
   chunkHeight := NumGet(BITMAP, 8, "UInt")
   Return true
}

BuildImg(id1, id2, file, zoom, width, height, chunkWidth, chunkHeight, outputTif) {
   static preUrl := "https://content.prlib.ru/fcgi-bin/iipsrv.fcgi?FIF=/var/data/scans/public/"
   
   countWidth  := Ceil(width/chunkWidth)
   countHeight := Ceil(height/chunkHeight)
   chunkCount := countWidth*countHeight
   
   GdipInst := new GDIp
   pBitmap := GdipInst.CreateBitmap(width, height)
   G := GdipInst.GraphicsFromImage(pBitmap)
   
   Loop % chunkCount {
      ToolTip % A_Index . " of " . chunkCount . " is downloading ...", 2, 2, 1
      if !pIUnknown := GetImgResponseStream(preUrl . id1 . "/" . id2 . "/" . file . "&JTL=" . zoom . "," . A_Index - 1) {
         MsgBox, 4,, Failed to load a chunk. Continue?
         IfMsgBox, No
            break
         else
            continue
      }
      pBitmapChunk := GdipInst.BitmapFromIStream(pIUnknown)
      DllCall("OleAut32\VariantClear", "PtrP", pIUnknown)
      GdipInst.DrawImage(G, pBitmapChunk, chunkWidth*mod((A_Index - 1), countWidth)
                                        , chunkHeight*(A_Index//(countWidth + 0.01))
                                        , chunkWidth, chunkHeight, 0, 0, chunkWidth, chunkHeight)
      GdipInst.DisposeImage(pBitmapChunk)
   }
   ToolTip,,,, 1
   GdipInst.SaveBitmap(pBitmap, outputTif)
   GdipInst.DeleteGraphics(G)
   GdipInst.DisposeImage(pBitmap)
}

GetHtml(url) {
   whr := ComObjCreate("Msxml2.XMLHTTP.6.0")
   whr.Open("GET", url, false)
   whr.SetRequestHeader("Pragma", "no-cache")
   whr.SetRequestHeader("Cache-Control", "no-cache, no-store")
   whr.Send()
   Return html := whr.ResponseText
}

GetJS() {
   static doc, JS
   if !doc {
       doc := ComObjCreate("htmlfile")
       doc.write("<meta http-equiv=""X-UA-Compatible"" content=""IE=9"">")
       JS := doc.parentWindow
   }
   Return JS
}

GetHBitmapFromImageURL(url)  {
   if !pIUnknown := GetImgResponseStream(url)
      Return
   GdipInst := new GDIp
   pBitmap := GdipInst.BitmapFromIStream(pIUnknown)
   DllCall("OleAut32\VariantClear", "PtrP", pIUnknown)
   hBitmap := GdipInst.CreateHBitmapFromBitmap(pBitmap)
   GdipInst.DisposeImage(pBitmap)
   Return hBitmap
}

GetImgResponseStream(url) {
   whr := ComObjCreate("WinHttp.WinHttpRequest.5.1")
   whr.Open("GET", url, false)
   whr.Send()
   if (whr.Status != 200)  {
      MsgBox, Failed to load the image!
      Return
   }
   contentType := whr.GetResponseHeader("Content-Type")
   if !InStr(contentType, "image")  {
      MsgBox, URL doesn't link to an image!
      Return
   }
   Return whr.ResponseStream
}

class GDIp   {
   __New() {
      if !DllCall("GetModuleHandle", "Str", "gdiplus", "Ptr")
         DllCall("LoadLibrary", "Str", "gdiplus")
      VarSetCapacity(si, A_PtrSize = 8 ? 24 : 16, 0), si := Chr(1)
      DllCall("gdiplus\GdiplusStartup", "UPtrP", pToken, "Ptr", &si, "Ptr", 0)
      this.token := pToken
   }
   
   __Delete()  {
      DllCall("gdiplus\GdiplusShutdown", "Ptr", this.token)
      if hModule := DllCall("GetModuleHandle", "Str", "gdiplus", "Ptr")
         DllCall("FreeLibrary", "Ptr", hModule)
   }
   
   BitmapFromIStream(pIUnknown)  {
      static IID_IStream := "{0000000C-0000-0000-C000-000000000046}"
      pIStream := ComObjQuery(pIUnknown, IID_IStream)
      DllCall("gdiplus\GdipCreateBitmapFromStream", "Ptr", pIStream, "PtrP", pBitmap)
      ObjRelease(pIStream)
      Return pBitmap
   }
   
   CreateHBitmapFromBitmap(pBitmap) {
      DllCall("gdiplus\GdipCreateHBITMAPFromBitmap", "Ptr", pBitmap, "PtrP", hBitmap, "UInt", 0xFFFFFFFF)
      Return hBitmap
   }
   
   CreateBitmap(Width, Height, Format=0x26200A) {
       DllCall("gdiplus\GdipCreateBitmapFromScan0", "Int", Width, "Int", Height, "Int", 0, "Int", Format, "Ptr", 0, "PtrP", pBitmap)
       Return pBitmap
   }
   
   GraphicsFromImage(pBitmap) {
      DllCall("gdiplus\GdipGetImageGraphicsContext", "Ptr", pBitmap, "PtrP", pGraphics)
      return pGraphics
   }
   
   DrawImage(pGraphics, pBitmap, dx, dy, dw, dh, sx, sy, sw, sh) {
      Return DllCall("gdiplus\GdipDrawImageRectRect", "Ptr", pGraphics, "Ptr", pBitmap
                                                    , "Float", dx, "Float", dy, "Float", dw, "Float", dh
                                                    , "Float", sx, "Float", sy, "Float", sw, "Float", sh
                                                    , "Int", 2, "Ptr", 0, "Ptr", 0, "Ptr", 0)
   }
   
   SaveBitmap(pBitmap, ByRef info, Quality := 75, tobuff := "")
   {
      ; info — если копируем в буфер, тогда расширение файла, если в файл, тогда путь к файлу
      if tobuff
         Extension := info
      else
         SplitPath, info,,, Extension
      if Extension not in BMP,DIB,RLE,JPG,JPEG,JPE,JFIF,GIF,TIF,TIFF,PNG
         return -1

      DllCall("gdiplus\GdipGetImageEncodersSize", "UintP", nCount, "UintP", nSize)
      VarSetCapacity(ci, nSize)
      DllCall("gdiplus\GdipGetImageEncoders", "UInt", nCount, "UInt", nSize, "Ptr", &ci)
      if !(nCount && nSize)
         return -2
      
      Loop, % nCount  {
         sString := StrGet(NumGet(ci, (idx := (48+7*A_PtrSize)*(A_Index-1))+32+3*A_PtrSize), "UTF-16")
         if !InStr(sString, "*." Extension)
            continue
         
         pCodec := &ci+idx
         break
      }
      
      if !pCodec
         return -3
      
      if RegExMatch(Extension, "i)^J(PG|PEG|PE|FIF)$") && Quality != 75  {
         DllCall("gdiplus\GdipGetEncoderParameterListSize", "Ptr", pBitmap, "Ptr", pCodec, "UintP", nSize)
         VarSetCapacity(EncoderParameters, nSize, 0)
         DllCall("gdiplus\GdipGetEncoderParameterList", "Ptr", pBitmap, "Ptr", pCodec, "UInt", nSize, "Ptr", &EncoderParameters)
         Loop, % NumGet(EncoderParameters, "UInt")
         {
            elem := (24+A_PtrSize)*(A_Index-1) + 4 + (pad := A_PtrSize = 8 ? 4 : 0)
            if (NumGet(EncoderParameters, elem+16, "UInt") = 1) && (NumGet(EncoderParameters, elem+20, "UInt") = 6)
            {
               p := elem+&EncoderParameters-pad-4
               NumPut(Quality, NumGet(NumPut(4, NumPut(1, p+0)+20, "UInt")), "UInt")
               break
            }
         }      
      }
      if !tobuff
         E := DllCall("gdiplus\GdipSaveImageToFile", "Ptr", pBitmap, "WStr", info, "Ptr", pCodec, "UInt", p ? p : 0)
      else  {
         DllCall( "ole32\CreateStreamOnHGlobal", "UInt", 0, "Int", 1, "PtrP", pStream )
         if !E := DllCall( "gdiplus\GdipSaveImageToStream", "Ptr", pBitmap, "Ptr", pStream, "Ptr", pCodec, "UInt", p ? p : 0 )  {
            DllCall( "ole32\GetHGlobalFromStream", "Ptr", pStream, "PtrP", hData )
            pData := DllCall( "GlobalLock", "Ptr", hData, "Ptr" )
            nSize := DllCall( "GlobalSize", "Ptr", hData, "Ptr" )
            VarSetCapacity( info, 0), VarSetCapacity( info, nSize, 0 )
            DllCall( "RtlMoveMemory", "Ptr", &info, "Ptr", pData, "Ptr", nSize )
            DllCall( "GlobalUnlock", "Ptr", hData )
            DllCall( "GlobalFree", "Ptr", hData )
         }
         ObjRelease(pStream)
      }
      return E ? -4 : tobuff ? nSize : 0
   }
   
   DisposeImage(pBitmap) {
      return DllCall("gdiplus\GdipDisposeImage", "Ptr", pBitmap)
   }
   
   DeleteGraphics(pGraphics) {
      return DllCall("gdiplus\GdipDeleteGraphics", "Ptr", pGraphics)
   }
}
Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder
+ DD

108

Re: AHK: Объединить кусочки картинок в одно целое

Malcev пишет:

Я не понимаю одного, почему эти библиотеки не дают скачать?
Ведь всё-равно кому надо выкачает.

А если бы к примеру фрагменты изображений накладывались бы случайным образом, а json их структурой не выдавался, шифровался и тп — тоже выкачали бы?

109

Re: AHK: Объединить кусочки картинок в одно целое

Хотя в этом случае уже с экрана можно было бы скринить).

110

Re: AHK: Объединить кусочки картинок в одно целое

DD пишет:

А если бы к примеру фрагменты изображений накладывались бы случайным образом, а json их структурой не выдавался, шифровался и тп — тоже выкачали бы?

Вы ссылку приведите, а там посмотрим.
Думаю, что всё, что мы получаем на монитор, можно перехватить.

111

Re: AHK: Объединить кусочки картинок в одно целое

Да я просто спросил, теоретически).

112

Re: AHK: Объединить кусочки картинок в одно целое

Единственный способ защитить контент - это накладывать вотермарки.
Но всё-равно, если ваш товар будет пользоваться спросом, то найдутся умельцы, которые взломают сервер и будут продавать раз в 10 дешевле.

113 (изменено: DD, 2020-12-31 12:57:35)

Re: AHK: Объединить кусочки картинок в одно целое

Malcev пишет:

Если это канвас, то можно так:

oIE := ComObjCreate("InternetExplorer.Application")
oIE.visible := True
oIE.Navigate("https://www.w3schools.com/html/html5_canvas.asp")
While oIE.readyState != 4 || oIE.document.readyState != "complete" || oIE.busy
   Sleep, 10
canvas := oIE.document.getElementById("myCanvas")
oIE.document.parentwindow.navigator.msSaveBlob(canvas.msToBlob(), "canvas.png")
msgbox done

Нашлась такая штука, которой можно скармливать ссылки с нарезанными изображениями, преобразуемые затем вроде бы в канвас. Как получить потом это собранное изображение?

114

Re: AHK: Объединить кусочки картинок в одно целое

Сайт http://ophir.alwaysdata.net/ в IE не полнофункционально работает, видимо поэтому не  срабатывает.

115 (изменено: DD, 2021-01-01 14:56:57)

Re: AHK: Объединить кусочки картинок в одно целое

Тут выше в коде есть фрагмент, объединяющий кусочки картинок в памяти, по ходу скачивания. Как совместить эту возможность с кодом из 30-го сообщения, объединяющим кусочки с диска?

#NoEnv
SetBatchLines, -1
pToken := Gdip_Startup()

offset := -1
ext = jpg
OutputFile := A_ScriptDir "\__merged.png"

arr := []  
off := []
off.X[1] := off.Y[1] := aw := ah := 0

Loop, %A_ScriptDir%\*.%ext%
{
	If !RegExMatch(A_LoopFileName, "S)^(\d+)_(\d+)\." ext "$", F)
		Continue
	col := F1 + 1, row := F2 + 1
	If !arr[col]
		arr[col] := []
	arr[col][row] := A_LoopFileFullPath
} 
 
If !arr[1][1]
	ExitApp 

for col, rows in arr
	for row, path in rows
	{
		pBitmap := Gdip_CreateBitmapFromFile(path)
		Gdip_GetImageDimensions(pBitmap, w, h) 
		If (row = 1) 
			aw := off.X[col + 1] := aw + w + offset
		If (col = 1)
			ah := off.Y[row + 1] := ah + h + offset
		arr[col][row] := {pBitmap: pBitmap, w: w, h: h}
	} 
	
pBitmapNew := Gdip_CreateBitmap(aw, ah)
G := Gdip_GraphicsFromImage(pBitmapNew)
Gdip_SetSmoothingMode(G, 4)
Gdip_SetInterpolationMode(G, 7)

for col, rows in arr 
	for row, obj in rows 
		Gdip_DrawImage(G, obj.pBitmap, off.X[col], off.Y[row], obj.w, obj.h, 0, 0, obj.w, obj.h)
		, Gdip_DisposeImage(obj.pBitmap)   

Gdip_SaveBitmapToFile(pBitmapNew, OutputFile)
Gdip_DisposeImage(pBitmapNew)
Gdip_DeleteGraphics(G)
Gdip_Shutdown(pToken)
run %OutputFile%
ExitApp

116

Re: AHK: Объединить кусочки картинок в одно целое

Так тот что выше тоже в файл сохраняет, зачем объединять.

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru
Win10x64 v20H2, AutoHotkey_L v1.1.33.02 (Unicode 32-bit). AhkSpy, Hotkey, ClockGui

117 (изменено: DD, 2021-01-03 14:48:50)

Re: AHK: Объединить кусочки картинок в одно целое

serzh82saratov
Имелось в виду, что скрипт teadrinker`a скачивает кусочки и тут же собирает из них изображение в памяти, а Ваш — собирает изображение из уже скачанных кусков картинок, находящихся на диске. То есть, для практического использования хотелось бы избежать необходимости сохранять все фрагменты картинок на диск, чтобы скачивание и объединение из кусков происходило в памяти.

118

Re: AHK: Объединить кусочки картинок в одно целое

DD пишет:

скрипт teadrinker`a скачивает кусочки и тут же собирает из них изображение в памяти

Ну, и сохраняет на диск склееное изображение, что не так?

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru
Win10x64 v20H2, AutoHotkey_L v1.1.33.02 (Unicode 32-bit). AhkSpy, Hotkey, ClockGui

119

Re: AHK: Объединить кусочки картинок в одно целое

Он конечно сохранит склеенное изображение, но перед этим для каждой страницы придется скачивать на диск почти 700 фрагментов этого изображения, отчего хотелось бы, чтобы подготовительный сбор кусков производился в памяти.

120

Re: AHK: Объединить кусочки картинок в одно целое

Оба моих сообщения про код teadrinker.

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru
Win10x64 v20H2, AutoHotkey_L v1.1.33.02 (Unicode 32-bit). AhkSpy, Hotkey, ClockGui

121

Re: AHK: Объединить кусочки картинок в одно целое

То есть, с этим кодом по такому же принципу можно собирать изображения?

122

Re: AHK: Объединить кусочки картинок в одно целое

Насколько помню, там координаты отдельных кусков брались из файла, а тут алгоритм исходит из наибольшего числа в именах кусочков -- плюс смещение на 2 пикселя.

123

Re: AHK: Объединить кусочки картинок в одно целое

По какому алгоритму, я не помню ни про свой, ни конечно про чужой.

DD пишет:

То есть, с этим кодом по такому же принципу можно собирать изображения?

Ну вы код от teadrinker запускали? После всех скачиваний, в папке скрипта появляется картинка. Потому я совсем не понимаю о чём вы ведёте речь.

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru
Win10x64 v20H2, AutoHotkey_L v1.1.33.02 (Unicode 32-bit). AhkSpy, Hotkey, ClockGui

124

Re: AHK: Объединить кусочки картинок в одно целое

serzh82saratov пишет:
DD пишет:

а как скрипт узнаёт, где край изображения — где надо остановиться и снизу начать новый сбор?

		w := w > ++F1 ? w : F1
		h := h > ++F2 ? h : F2 

Он сначала перебирает все файлы, и узнаёт максимальные числа в их названиях. Первое число - колонки, второе - строки.

Код от teadrinker запускал и картинка собирается, но это происходит в отношении другого принципа сбора и к тому же — сразу в памяти, потому использовать как дополнение к Вашему коду не представляется возможным. Ваш код собирает фрагменты с диска, а другой — в памяти.

125

Re: AHK: Объединить кусочки картинок в одно целое

DD пишет:

Ваш код собирает фрагменты с диска, а другой — в памяти.

Мой с диска, а его из интернета, а картинку собирают оба одинаково в памяти.

DD пишет:

Код от teadrinker запускал и картинка собирается, но это происходит в отношении другого принципа сбора

Так вы опишите чем он не устраивает, или приведите пример с которым он не работает.
Ходите вокруг да около.

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru
Win10x64 v20H2, AutoHotkey_L v1.1.33.02 (Unicode 32-bit). AhkSpy, Hotkey, ClockGui

126

Re: AHK: Объединить кусочки картинок в одно целое

Действительно, оба в памяти собирают). Тогда хотелось бы понять, как подавать Вашему коду фрагменты для сбора (вместо «Loop, %A_ScriptDir%\*.%ext%»)? Ведь, как Вы писали, «он сначала перебирает все файлы, и узнаёт максимальные числа в их названиях». То есть, они должны быть уже скачаны?

127

Re: AHK: Объединить кусочки картинок в одно целое

DD пишет:

Сайт http://ophir.alwaysdata.net/ в IE не полнофункционально работает, видимо поэтому не  срабатывает.

С IE всё меньше и меньше сайтов работает, переходите на хром.

128

Re: AHK: Объединить кусочки картинок в одно целое

Да я IE никогда не пользовался для интернета — просто Fiddler (анализатор сетевого трафика) перехватывает запросы из IE, а из Хрома — нет.

129 (изменено: DD, 2021-01-03 21:37:39)

Re: AHK: Объединить кусочки картинок в одно целое

Вроде бы, код от teadrinker анализирует координаты каждого фрагмента из json-файла для каждой страницы, а у Вас по-другому работает.

130

Re: AHK: Объединить кусочки картинок в одно целое

Всё он (Fiddler) прекрасно работает.
Но для сохранения канваса с http://ophir.alwaysdata.net/dezoomify/dezoomify.html вам не нужен перехватчик траффика.
Достаточно этот код переделать под хром.

oIE := ComObjCreate("InternetExplorer.Application")
oIE.visible := True
oIE.Navigate("https://www.w3schools.com/html/html5_canvas.asp")
While oIE.readyState != 4 || oIE.document.readyState != "complete" || oIE.busy
   Sleep, 10
canvas := oIE.document.getElementById("myCanvas")
oIE.document.parentwindow.navigator.msSaveBlob(canvas.msToBlob(), "canvas.png")
msgbox done

131

Re: AHK: Объединить кусочки картинок в одно целое

Malcev
Забыл) Я упомянул IE, потому что Ваш скрипт, который я там же приводил — он вроде работает с окном из IE.

132

Re: AHK: Объединить кусочки картинок в одно целое

Malcev пишет:

Всё он (Fiddler) прекрасно работает.

Он у Вас и из Хрома перехватывает запросы?

133

Re: AHK: Объединить кусочки картинок в одно целое

Когда был установлен - перехватывал.

134

Re: AHK: Объединить кусочки картинок в одно целое

Malcev пишет:

вам не нужен перехватчик траффика

Мне хотелось попробовать через этот сервис наладить скачивание — давать ему ссылки, чтобы он собирал, а потом брать результат. Но там это непонятно происходит.

135 (изменено: DD, 2021-01-03 22:03:09)

Re: AHK: Объединить кусочки картинок в одно целое

Но самое главное: то, как они собирают — это не точно. В скрипте serzh82saratov это точнее сделано. Ниже по ссылке можно посмотреть разницу. Видно, что где на сайте алгоритм обработал первые строки по горизонтали и вертикали (обведены красным) — там стебли смещаются, блики  и линии раздваиваются и т.п. — https://yadi.sk/d/Jd8Sj-ohOxq_yQ.

136

Re: AHK: Объединить кусочки картинок в одно целое

Сайт создает канвас с полученными изображениями.
Который вам необходимо скачать.
Этим кодом

oHTTP := ComObjCreate("WinHttp.WinHttpRequest.5.1")
oHTTP.Open("GET", "https://www.w3schools.com/html/html5_canvas.asp")
oHTTP.Send()
oHTTP.WaitForResponse()
oHTML := ComObjCreate("HTMLFile")
oHTML.open()
oHTML.write("<meta http-equiv=""X-UA-Compatible"" content=""IE=edge"">")
oHTML.write(oHTTP.ResponseText)
oHTML.close()
loop
{
   if (oHTML.readyState = "complete")
      break
   sleep 10
}
canvas := oHTML.getElementById("myCanvas")
nBytes := Base64Dec(SubStr(canvas.toDataURL(), 23), Bin)
File := FileOpen("canvas.png", "w")
File.RawWrite(Bin, nBytes)
File.Close()
msgbox done

Base64Dec( ByRef B64, ByRef Bin ) {  ; By SKAN / 18-Aug-2017
Local Rqd := 0, BLen := StrLen(B64)                 ; CRYPT_STRING_BASE64 := 0x1
  DllCall( "Crypt32.dll\CryptStringToBinary", "Str",B64, "UInt",BLen, "UInt",0x1
         , "UInt",0, "UIntP",Rqd, "Int",0, "Int",0 )
  VarSetCapacity( Bin, 128 ), VarSetCapacity( Bin, 0 ),  VarSetCapacity( Bin, Rqd, 0 )
  DllCall( "Crypt32.dll\CryptStringToBinary", "Str",B64, "UInt",BLen, "UInt",0x1
         , "Ptr",&Bin, "UIntP",Rqd, "Int",0, "Int",0 )
Return Rqd
}

и этим

oIE := ComObjCreate("InternetExplorer.Application")
oIE.visible := True
oIE.Navigate("https://www.w3schools.com/html/html5_canvas.asp")
While oIE.readyState != 4 || oIE.document.readyState != "complete" || oIE.busy
   Sleep, 10
canvas := oIE.document.getElementById("myCanvas")
oIE.document.parentwindow.navigator.msSaveBlob(canvas.msToBlob(), "canvas.png")
msgbox done

не получится, так-как сайт с IE не работает.
Поэтому либо самому собирать через тот же gdi+, либо автоматизировать через хром.

+ DD

137

Re: AHK: Объединить кусочки картинок в одно целое

DD пишет:

то, как они собирают — это не точно

Кто они?

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru
Win10x64 v20H2, AutoHotkey_L v1.1.33.02 (Unicode 32-bit). AhkSpy, Hotkey, ClockGui

138

Re: AHK: Объединить кусочки картинок в одно целое

Авторы сервиса с их алгоритмами).

139

Re: AHK: Объединить кусочки картинок в одно целое

Значит используйте код teadrinker.

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru
Win10x64 v20H2, AutoHotkey_L v1.1.33.02 (Unicode 32-bit). AhkSpy, Hotkey, ClockGui

140 (изменено: DD, 2021-01-05 13:17:14)

Re: AHK: Объединить кусочки картинок в одно целое

serzh82saratov
Сергей, с чем может быть связано, что когда использую ваш код в цикле, где он должен раз за разом собирать изображение из фрагментов — он отрабатывает только в первом цикле, а на втором и последующих сборка не происходит? Может, надо какие-то данные очищать?

141

Re: AHK: Объединить кусочки картинок в одно целое

Вы же ранее писали что он работает хорошо.

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru
Win10x64 v20H2, AutoHotkey_L v1.1.33.02 (Unicode 32-bit). AhkSpy, Hotkey, ClockGui

142

Re: AHK: Объединить кусочки картинок в одно целое

А вы имеете в виду что зацикливаете весь мой код.
Тогда вы уже ответили на свой вопрос: надо какие-то данные очищать.

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru
Win10x64 v20H2, AutoHotkey_L v1.1.33.02 (Unicode 32-bit). AhkSpy, Hotkey, ClockGui

143

Re: AHK: Объединить кусочки картинок в одно целое

Я и не говорю, что плохо работает — просто видимо при работе в цикле, надо какие-то данные очищать.

144

Re: AHK: Объединить кусочки картинок в одно целое

serzh82saratov пишет:

А вы имеете в виду что зацикливаете весь мой код.
Тогда вы уже ответили на свой вопрос: надо какие-то данные очищать.

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru
Win10x64 v20H2, AutoHotkey_L v1.1.33.02 (Unicode 32-bit). AhkSpy, Hotkey, ClockGui

145

Re: AHK: Объединить кусочки картинок в одно целое

Вот эти чищу, но без результата:


pToken := ""
pBitmapNew := ""
pBitmap := ""
aw := ""
ah := ""
rows := ""
col := ""
path := ""
G := ""
arr := ""
off := ""

146

Re: AHK: Объединить кусочки картинок в одно целое

А весь код выложить вы конечно с первой попытки не можете, и предлагаете мне угадывать как он у вас может выглядеть (

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru
Win10x64 v20H2, AutoHotkey_L v1.1.33.02 (Unicode 32-bit). AhkSpy, Hotkey, ClockGui

147

Re: AHK: Объединить кусочки картинок в одно целое

serzh82saratov
Оказалось, что строку из начала скрипта (pToken := Gdip_Startup()), надо было в метку перенести, перед основным кодом сбора.

148

Re: AHK: Объединить кусочки картинок в одно целое

serzh82saratov пишет:

+1 к умению всё сделать через *опу

Я конечно так делать умею, но не всё — не надо преувеличивать). Что не так с переносом переменной pToken в метку?

149

Re: AHK: Объединить кусочки картинок в одно целое

То что каждый раз грузит Gdip.

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru
Win10x64 v20H2, AutoHotkey_L v1.1.33.02 (Unicode 32-bit). AhkSpy, Hotkey, ClockGui

150 (изменено: serzh82saratov, 2021-01-11 14:43:15)

Re: AHK: Объединить кусочки картинок в одно целое

Наверняка так тоже будет работать.


#NoEnv
SetBatchLines, -1
pToken := Gdip_Startup()

offset := -1
ext = jpg

Loop, Parse, список итоговых файлов
{
	
	OutputFile := A_LoopField
	Folder = папка с фрагментами
	arr := []  
	off := []
	off.X[1] := off.Y[1] := aw := ah := 0
	
	Loop, %A_ScriptDir%\%Folder%\*.%ext%
	{
		If !RegExMatch(A_LoopFileName, "S)^(\d+)_(\d+)\." ext "$", F)
			Continue
		col := F1 + 1, row := F2 + 1
		If !arr[col]
			arr[col] := []
		arr[col][row] := A_LoopFileFullPath
	} 
	 
	If !arr[1][1]
		ExitApp 
	
	for col, rows in arr
		for row, path in rows
		{
			pBitmap := Gdip_CreateBitmapFromFile(path)
			Gdip_GetImageDimensions(pBitmap, w, h) 
			If (row = 1) 
				aw := off.X[col + 1] := aw + w + offset
			If (col = 1)
				ah := off.Y[row + 1] := ah + h + offset
			arr[col][row] := {pBitmap: pBitmap, w: w, h: h}
		} 
		
	pBitmapNew := Gdip_CreateBitmap(aw, ah)
	G := Gdip_GraphicsFromImage(pBitmapNew)
	Gdip_SetSmoothingMode(G, 4)
	Gdip_SetInterpolationMode(G, 7)
	
	for col, rows in arr 
		for row, obj in rows 
			Gdip_DrawImage(G, obj.pBitmap, off.X[col], off.Y[row], obj.w, obj.h, 0, 0, obj.w, obj.h)
			, Gdip_DisposeImage(obj.pBitmap)   
	
	Gdip_SaveBitmapToFile(pBitmapNew, OutputFile)
	Gdip_DisposeImage(pBitmapNew)
	Gdip_DeleteGraphics(G)
}


Gdip_Shutdown(pToken) 
ExitApp
По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru
Win10x64 v20H2, AutoHotkey_L v1.1.33.02 (Unicode 32-bit). AhkSpy, Hotkey, ClockGui
+ DD

151 (изменено: DD, 2021-01-12 02:55:14)

Re: AHK: Объединить кусочки картинок в одно целое

Сергей, как вы писали — перед сборкой изображения, ваш скрипт перебирает все файлы и узнаёт максимальные числа в их названиях. Вот используя следующий код, который надёжно скачивает фрагменты — нельзя ли запоминать эти максимальные числа из названий и отрабатывать основную часть кода по сбору? То есть, правильно понимаю, что основная задача — это скачивать эти фрагменты в память, тогда как получить инфу для сбора код ниже позволяет? А числа код получает всегда одинаковые — то есть, если один раз по вертикали или горизонтали было получено 20 фрагментов, то и дальше это число не будет меняться по тем же сторонам:

OutputFolder := A_ScriptDir "\_Tmp"
FileGetAttrib, attrib, %OutputFolder%\
   IfNotInString, attrib, D
      FileCreateDir, %OutputFolder%\

num1 := num2 := 0
Loop
{
   sleep 111
   loop  ;CONNECT_LOOP
   {     ;CONNECT_LOOP
      HTTP := ComObjCreate("WinHTTP.WinHTTPRequest.5.1")
      HTTP.Open("GET", "http://www.bl.uk/manuscripts/Proxy.ashx?view=yates_thompson_ms_36_f001r_files/13/" num1 "_" num2 ".jpg", true)
      HTTP.SetRequestHeader("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.79 Safari/537.36")
      HTTP.SetRequestHeader("Pragma", "no-cache")
      HTTP.SetRequestHeader("If-Modified-Since", "Sat, 1 Jan 2000 00:00:00 GMT")
      try {
         HTTP.Send()
         HTTP.WaitForResponse()
         Body := HTTP.ResponseBody
         RTxt := HTTP.ResponseText
         
         If InStr(RTxt, "ÿØÿà")
         {
            pData := NumGet(ComObjValue(Body), A_PtrSize = 8? 16:12, "ptr")
            File := FileOpen(OutputFolder "\" num1 "_" num2 ".jpg", "w")
            File.RawWrite(pData + 0, Body.MaxIndex() + 1)
            File.Close()
            break
         }
         If (num2 = 0) AND InStr(RTxt, "/NoImage.jpg") {
            EndMode := 1
            break
         }
         If InStr(RTxt, "/NoImage.jpg") {
            num1++
            num2 := 0
         }
      }
      catch {
         Sleep, 5000
      }
   }     ;CONNECT_LOOP

   If (EndMode == 1)
      break
   RTxt := EndMode := ""
   num2++
}

152 (изменено: serzh82saratov, 2021-01-12 22:12:19)

Re: AHK: Объединить кусочки картинок в одно целое

+ открыть спойлер

#NoEnv
SetBatchLines, -1

pages = 
(  
http://www.bl.uk/manuscripts/Proxy.ashx?view=yates_thompson_ms_36_f001r_files/10
http://www.bl.uk/manuscripts/Proxy.ashx?view=yates_thompson_ms_36_f001r_files/11
)

offset := -1
OutputFileName := A_Desktop "\merged_" 
OutputExt = png

OutputFolder := A_ScriptDir "\_Tmp"
FileGetAttrib, attrib, %OutputFolder%\
   IfNotInString, attrib, D
      FileCreateDir, %OutputFolder%\

pToken := Gdip_Startup()
HTTP := ComObjCreate("WinHTTP.WinHTTPRequest.5.1")

Loop, Parse, pages, `n, `r  
{
	num1 := num2 := 0, arrB := {}
   page := RegExReplace(A_LoopField, ".*?(\d+)$", "$1") 
   loop  
   {     
      HTTP.Open("GET", A_LoopField "/" num1 "_" num2 ".jpg", true)
      HTTP.SetRequestHeader("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.79 Safari/537.36")
      HTTP.SetRequestHeader("Pragma", "no-cache")
      HTTP.SetRequestHeader("If-Modified-Since", "Sat, 1 Jan 2000 00:00:00 GMT")
      try {
         HTTP.Send()
         HTTP.WaitForResponse() 
		 RTxt := HTTP.ResponseText
		 
         If InStr(RTxt, "ÿØÿà") {  
			ToolTip % "page: " page " picture: " num1 "_" num2 ".jpg" " is downloading ...", 2, 2, 1   
            arrB.Push([num1, num2++, BitmapFromIStream(HTTP.ResponseStream)]) 
            Continue
         }
         If (num2 = 0) AND InStr(RTxt, "/NoImage.jpg") { 
            break
         }
         If InStr(RTxt, "/NoImage.jpg") {
            num1++, num2 := 0
         }
      }
      catch {
         Throw Exception(num1 "_" num2, -1)
      }
   } 
   merged(arrB, OutputFileName, OutputExt, page, offset)
}

HTTP := ""
Gdip_Shutdown(pToken)
ExitApp
 
merged(arrB, OutputFileName, OutputExt, page, offset) { 
	OutputFile := OutputFileName page "." OutputExt
	arr := []
	off := []
	off.X[1] := off.Y[1] := aw := ah := 0
	
	for key, obj in arrB
	{  
		col := obj[1] + 1, row := obj[2] + 1
		If !arr[col]
			arr[col] := []
		arr[col][row] := obj[3]
	} 
	 
	If !arr[1][1]
		ExitApp 
	
	for col, rows in arr
		for row, pBitmap in rows
		{
			Gdip_GetImageDimensions(pBitmap, w, h)  
			If (row = 1) 
				aw := off.X[col + 1] := aw + w + offset
			If (col = 1)
				ah := off.Y[row + 1] := ah + h + offset
			arr[col][row] := {pBitmap: pBitmap, w: w, h: h}
		} 
	pBitmapNew := Gdip_CreateBitmap(aw, ah)
	G := Gdip_GraphicsFromImage(pBitmapNew)
	Gdip_SetSmoothingMode(G, 4)
	Gdip_SetInterpolationMode(G, 7)
	
	for col, rows in arr 
		for row, obj in rows 
			Gdip_DrawImage(G, obj.pBitmap, off.X[col], off.Y[row], obj.w, obj.h, 0, 0, obj.w, obj.h)
			, Gdip_DisposeImage(obj.pBitmap)   
	
	Gdip_SaveBitmapToFile(pBitmapNew, OutputFile)
	Gdip_DisposeImage(pBitmapNew)
	Gdip_DeleteGraphics(G)
	run %OutputFile% 
}
 
BitmapFromIStream(pIUnknown)  {
	static IID_IStream := "{0000000C-0000-0000-C000-000000000046}"
	pIStream := ComObjQuery(pIUnknown, IID_IStream)
	DllCall("gdiplus\GdipCreateBitmapFromStream", "Ptr", pIStream, "PtrP", pBitmap)
	ObjRelease(pIStream)
	DllCall("OleAut32\VariantClear", "PtrP", pIUnknown)
	Return pBitmap
}
По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru
Win10x64 v20H2, AutoHotkey_L v1.1.33.02 (Unicode 32-bit). AhkSpy, Hotkey, ClockGui

153

Re: AHK: Объединить кусочки картинок в одно целое

Можно ускорить отсекая заведомо неправильные запросы, и сократить merged.


#NoEnv
SetBatchLines, -1 

pages = 
(  
yates_thompson_ms_36_f001r_files/10
yates_thompson_ms_36_f001r_files/11
yates_thompson_ms_36_f001r_files/13
)

offset := -1
OutputFile := A_Desktop "\" 
OutputExt = png

OutputFolder := A_ScriptDir "\_Tmp"
FileGetAttrib, attrib, %OutputFolder%\
IfNotInString, attrib, D
  FileCreateDir, %OutputFolder%\

pToken := Gdip_Startup()
HTTP := ComObjCreate("WinHTTP.WinHTTPRequest.5.1")

Loop, Parse, pages, `n, `r  
{
   row := col := 0, arr := [], off := {aw:0, ah:0}, colmax := -1 
   loop  
   {     
      HTTP.Open("GET", "http://www.bl.uk/manuscripts/Proxy.ashx?view=" A_LoopField "/" row "_" col ".jpg", true)
      HTTP.SetRequestHeader("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.79 Safari/537.36")
      HTTP.SetRequestHeader("Pragma", "no-cache")
      HTTP.SetRequestHeader("If-Modified-Since", "Sat, 1 Jan 2000 00:00:00 GMT")
      try {
         HTTP.Send()
         HTTP.WaitForResponse() 
		 RTxt := HTTP.ResponseText
		 
         If InStr(RTxt, "ÿØÿà") {  
			ToolTip % A_LoopField " picture: " row "_" col ".jpg" " is downloading ...", 2, 2, 1  
			pBitmap := BitmapFromIStream(HTTP.ResponseStream)
			Gdip_GetImageDimensions(pBitmap, w, h)  
			If (row = 1) 
				off.ah := off.Y[col + 1] := off.ah + h + offset
			If (col = 1)
				off.aw := off.X[row + 1] := off.aw + w + offset 
			(!arr[row]) && (arr[row] := [])
            arr[row][col] := {pBitmap: pBitmap, w: w, h: h}
			col := col = colmax ? (0, row++) : col + 1
         }
         Else If InStr(RTxt, "/NoImage.jpg") {
			If (col = 0)
				break
            row++, colmax := col - 1, col := 0
         }
      }
      catch {
         Throw Exception(A_LoopField "`n" row "_" col, -1)
      }
   }
   If colmax < 0
		Throw Exception(A_LoopField "`n" row "_" col, -1)
	merged(arr, off, OutputFile StrReplace(A_LoopField, "/", "_") "." OutputExt)
}

HTTP := ""
Gdip_Shutdown(pToken)
ExitApp
 
merged(arr, off, OutputFile) { 
	pBitmapFile := Gdip_CreateBitmap(off.aw, off.ah)
	G := Gdip_GraphicsFromImage(pBitmapFile)
	Gdip_SetSmoothingMode(G, 4)
	Gdip_SetInterpolationMode(G, 7) 
	for row, obj1 in arr
		for col, obj2 in obj1 
			Gdip_DrawImage(G, obj2.pBitmap, off.X[row], off.Y[col], obj2.w, obj2.h, 0, 0, obj2.w, obj2.h)
			, Gdip_DisposeImage(obj2.pBitmap)
	Gdip_SaveBitmapToFile(pBitmapFile, OutputFile)
	Gdip_DisposeImage(pBitmapFile)
	Gdip_DeleteGraphics(G)
	run %OutputFile% 
}
 
BitmapFromIStream(pIUnknown)  {
	static IID_IStream := "{0000000C-0000-0000-C000-000000000046}"
	pIStream := ComObjQuery(pIUnknown, IID_IStream)
	DllCall("gdiplus\GdipCreateBitmapFromStream", "Ptr", pIStream, "PtrP", pBitmap)
	ObjRelease(pIStream)
	DllCall("OleAut32\VariantClear", "PtrP", pIUnknown)
	Return pBitmap
}
По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru
Win10x64 v20H2, AutoHotkey_L v1.1.33.02 (Unicode 32-bit). AhkSpy, Hotkey, ClockGui
+ DD

154

Re: AHK: Объединить кусочки картинок в одно целое

Вот спасибо, уважаемый!