Jump to content

Recommended Posts

Greetings friends!

I have been searching the help file and Google, with no success, to find a way to validate images from a folder and mark them somehow in a spreadsheet.

My context is: I made a code with the help of the community that captures images from SAP and saves them in a folder.  Now I'd like to identify which ones are black, if it's even possible. I read about PixelSearch, but did not get it to work. If someone could point me in the right direction, I'd appreciate it.

The code I'm using:

#include <File.au3>
#include <ScreenCapture.au3>

$x = InputBox("Title", "Amount of Images To Capture", "", "", 320, 150)
If @error Then Exit
$x = Number($x)

$y = InputBox("Title", "Batch Name", "", "", 320, 150)
If @error Then Exit
$y = String($y)

HotKeySet("{HOME}", "printscreen")

Func printscreen()
$FilePath =("C:\Fiscalizacao\Fotos"&"/")
$FileName = $y & " - "
$FileList = _FileListToArray($FilePath, $FileName & '*.jpg', 1)

If Not IsArray($FileList) Then
    $FileName&= '1.jpg'
Else
        $FileName &= $FileList[0] + 1 & '.jpg'
EndIf
_ScreenCapture_Capture($FilePath & "\" & $FileName, 354, 196, 673, 436)
EndFunc

HotKeySet("{BS}", "Terminate")
Func Terminate()
    Exit 0
EndFunc

For $i = 1 to $x

Opt("WinTitleMatchMode",2)
If NOT WinExists("Relatorio") Then
   MsgBox(0, "Atenção!", "Relatório do MOM deve estar aberto!")
   Call("Terminate")
EndIf
Opt("WinTitleMatchMode",2)
WinActivate("Relatorio")
Sleep (250)
Opt("WinTitleMatchMode",2)
SendKeepActive("Relatorio")
Send("{ENTER}")
Sleep (1000)
Send("{HOME}")
Sleep (200)
Opt("WinTitleMatchMode",2)
WinActivate("Relatorio")
Send("{DOWN}")

Next

 

Share this post


Link to post
Share on other sites

If it is pure black I believe you could use PixelCheckSum when the image is displayed.  But you could also use GDI+ to load the image in memory and check if pixels are black.  I trust that the second option would be faster, especially if you have a large number of images.

Share this post


Link to post
Share on other sites

Actually the images aren't always pure black. Sometimes lighter tones do appear. Right now what I'm doing is loading them up in a VBA form, to display them, then manually validate, the black ones.

 

Say, how could I use GDI+ with my code?

Share this post


Link to post
Share on other sites

You can try with _GDIPlus_BitmapLockBits. There is an example in the help file  To me it is not clear if you only need to validate black images or also ones that are not pure black. If it is the second case then it would be a good idea to define "black color"

Share this post


Link to post
Share on other sites

Here a basic example of how to check a specific pixel color of an image.jpg.   Now you will have to manage the different shades of black.  It will depend on how those shades appear in your images.  You could separate the pixels into RGB values and identify if it is close to black.  Anyway it will start you up...

#include <GDIPlus.au3>

Const $sFile = "Test.jpg"

_GDIPlus_Startup()
Local $hImage = _GDIPlus_ImageLoadFromFile($sFile)
If @error Then
  _GDIPlus_Shutdown()
  Exit MsgBox($MB_SYSTEMMODAL, "", "An error has occured - unable to load image!")
EndIf

Local $iW = _GDIPlus_ImageGetWidth($hImage), $iH = _GDIPlus_ImageGetHeight($hImage)     ;get width and height of the image
Local $tBitmapData = _GDIPlus_BitmapLockBits($hImage, 0, 0, $iW, $iH, $GDIP_ILMREAD, $GDIP_PXF32ARGB)     ;locks the bitmap for reading
Local $iScan0 = DllStructGetData($tBitmapData, "Scan0")     ;get scan0 (pixel data) from locked bitmap
Local $iSearchPixel = 0xFFFFFFFF     ; pure black
Local $tPixel = DllStructCreate("int[" & $iW * $iH & "];", $iScan0)
Local $iPixel, $iRowOffset

For $iY = 0 To $iH - 1
  $iRowOffset = $iY * $iW + 1
  For $iX = 0 To $iW - 1       ;get each pixel in each line and row
    $iPixel = DllStructGetData($tPixel, 1, $iRowOffset + $iX)         ;get pixel color
    If $iPixel = $iSearchPixel Then ConsoleWrite("color found" & @CRLF)
  Next
Next
_GDIPlus_BitmapUnlockBits($hImage, $tBitmapData)     ;unlocks the bitmap that was locked by _GDIPlus_BitmapLockBits

;cleanup resources
_GDIPlus_ImageDispose($hImage)
_GDIPlus_Shutdown()

 

Share this post


Link to post
Share on other sites

@ahmet the images are pictures taken on a field operation. Whey they are taken outside the parameters, they turn out "black", but not always pure black. Sometimes the result is a lighter shade of black. Nevertheless they have no content, which is what I'm trying to automate.

 

@Nine I have a large amount of files to analyze. I didn't quite get how to use your code to achieve that (I'm somewhat new to scripting in AutoIt). As far as I understood, the example covers one file at a time?

Share this post


Link to post
Share on other sites
1 minute ago, AnRios said:

As far as I understood, the example covers one file at a time?

Yes you will need to adapt the code for multiple files.  It is kind of easy to do, but for now make it work for one file.  Try different images, and when it is all good, then change it for multiple files.  Good luck. 

Share this post


Link to post
Share on other sites

Sorry, I tried to run it, but nothing happens. I used the location from which the images are stored. 

#include <GDIPlus.au3>

Const $sFile = "C:\Fiscalizacao\Fotos\Lote 01 - 1.jpg" ; here don't know if it's correct

_GDIPlus_Startup()
Local $hImage = _GDIPlus_ImageLoadFromFile($sFile)
If @error Then
  _GDIPlus_Shutdown()
  Exit MsgBox($MB_SYSTEMMODAL, "", "An error has occured - unable to load image!")
EndIf

 

Share this post


Link to post
Share on other sites

You copied just a few lines of code of my example !  And you say nothing happens ? What did you expect, some miracle ?  Copy my whole script, study it, open help file, read the explanations of each function, run all the examples of the help file related to those functions.  If it is still not clear, redo it until you have enough knowledge to modify the script in accordance of your needs.

Edited by Nine

Share this post


Link to post
Share on other sites

wouldnt there be noticeable difference in file size?  thought being: who cares what the data actually is, just throw out the ones that dont have enough of it? 


,-. .--. ________ .-. .-. ,---. ,-. .-. .-. .-.
|(| / /\ \ |\ /| |__ __||| | | || .-' | |/ / \ \_/ )/
(_) / /__\ \ |(\ / | )| | | `-' | | `-. | | / __ \ (_)
| | | __ | (_)\/ | (_) | | .-. | | .-' | | \ |__| ) (
| | | | |)| | \ / | | | | | |)| | `--. | |) \ | |
`-' |_| (_) | |\/| | `-' /( (_)/( __.' |((_)-' /(_|
'-' '-' (__) (__) (_) (__)

Share this post


Link to post
Share on other sites

Maybe this is something worth to investigate:

Edit:

It's really fast :). Here's a sample code which calculates the average color for every picture in a given directory.

16777216 = 0x000000 = black
33554431 = 0xFFFFFF = white

Set a threshold (try and error), maybe everything below 16777216 + 1000000 = 17777216 is black enough for you.

_ASM_BitmapGetAverageColorValue_Ex.zip

Edited by KaFu

Share this post


Link to post
Share on other sites

@Nine calm down pal.  Obviously I used the entire script. What I sent was just the part where I wasn't sure about. I read everything and I am studying, but sometimes you get to a point where you don't understand things, that's why I'm here asking.

Share this post


Link to post
Share on other sites
18 hours ago, Nine said:

No it was not obvious.  Beside your statement saying "Nothing happens" proves that you don't understand the basics of the script.

Your statement proves you have no education. I ran your code changing exclusively the file and nothing happened, I didn't know you were so senstitive to facts.

Edited by AnRios

Share this post


Link to post
Share on other sites

Guys, please slow down and stop making this personal. 

Just stick to the facts or don't reply.

Jos

Share this post


Link to post
Share on other sites
On 11/6/2019 at 3:18 PM, AnRios said:

Sorry, I tried to run it, but nothing happens. I used the location from which the images are stored. 

#include <GDIPlus.au3>

Const $sFile = "C:\Fiscalizacao\Fotos\Lote 01 - 1.jpg" ; here don't know if it's correct

_GDIPlus_Startup()
Local $hImage = _GDIPlus_ImageLoadFromFile($sFile)
If @error Then
  _GDIPlus_Shutdown()
  Exit MsgBox($MB_SYSTEMMODAL, "", "An error has occured - unable to load image!")
EndIf

 

please provide a sample image so i can test with your code. thanks. we can help you adapt @Nine's code. is this the total script that isn't working?

Edited by Earthshine

My resources are limited. You must ask the right questions

 

Share this post


Link to post
Share on other sites
11 minutes ago, Earthshine said:

please provide a sample image so i can test with your code. thanks. we can help you adapt @Nine's code.

Sure mate, thanks!

I know they all look pitch black, but some present slightly different shades.

No, I just posted the beggining because I didn't know If I put the source file in the right place. I tried the full code posted before.

#include <GDIPlus.au3>

Const $sFile = "Test.jpg" ; I just changed here from what I understood.

_GDIPlus_Startup()
Local $hImage = _GDIPlus_ImageLoadFromFile($sFile)
If @error Then
  _GDIPlus_Shutdown()
  Exit MsgBox($MB_SYSTEMMODAL, "", "An error has occured - unable to load image!")
EndIf

Local $iW = _GDIPlus_ImageGetWidth($hImage), $iH = _GDIPlus_ImageGetHeight($hImage)     ;get width and height of the image
Local $tBitmapData = _GDIPlus_BitmapLockBits($hImage, 0, 0, $iW, $iH, $GDIP_ILMREAD, $GDIP_PXF32ARGB)     ;locks the bitmap for reading
Local $iScan0 = DllStructGetData($tBitmapData, "Scan0")     ;get scan0 (pixel data) from locked bitmap
Local $iSearchPixel = 0xFFFFFFFF     ; pure black
Local $tPixel = DllStructCreate("int[" & $iW * $iH & "];", $iScan0)
Local $iPixel, $iRowOffset

For $iY = 0 To $iH - 1
  $iRowOffset = $iY * $iW + 1
  For $iX = 0 To $iW - 1       ;get each pixel in each line and row
    $iPixel = DllStructGetData($tPixel, 1, $iRowOffset + $iX)         ;get pixel color
    If $iPixel = $iSearchPixel Then ConsoleWrite("color found" & @CRLF)
  Next
Next
_GDIPlus_BitmapUnlockBits($hImage, $tBitmapData)     ;unlocks the bitmap that was locked by _GDIPlus_BitmapLockBits

;cleanup resources
_GDIPlus_ImageDispose($hImage)
_GDIPlus_Shutdown()

Lote 01 - 26.jpg

Lote 01 - 293.jpg

Lote 01 - 415.jpg

 

 

 

Edited by AnRios

Share this post


Link to post
Share on other sites

can you zip up a directory that has a couple of successful captures alongside some of these failures? 

I am still of the auspice that there is no need to read pixel values, nor even open the files.

 

**Or if sensitive can i see a screenshot of the directory in details view? my continued curiosity is about size discrepancies.

Edited by iamtheky

,-. .--. ________ .-. .-. ,---. ,-. .-. .-. .-.
|(| / /\ \ |\ /| |__ __||| | | || .-' | |/ / \ \_/ )/
(_) / /__\ \ |(\ / | )| | | `-' | | `-. | | / __ \ (_)
| | | __ | (_)\/ | (_) | | .-. | | .-' | | \ |__| ) (
| | | | |)| | \ / | | | | | |)| | `--. | |) \ | |
`-' |_| (_) | |\/| | `-' /( (_)/( __.' |((_)-' /(_|
'-' '-' (__) (__) (_) (__)

Share this post


Link to post
Share on other sites
13 minutes ago, iamtheky said:

can you zip up a directory that has a couple of successful captures alongside some of these failures? 

I am still of the auspice that there is no need to read pixel values, nor even open the files.

Ok friend, let's hope you are correct!


Here it goes the zipped directory and a screenshot of the situation. Several "good" images and a black one (failed).

Example.jpg

Pictures.zip

Share this post


Link to post
Share on other sites

2 failed

2failed.thumb.PNG.379f7edbbc4d4b5c2e8006588ffc8239.PNG


,-. .--. ________ .-. .-. ,---. ,-. .-. .-. .-.
|(| / /\ \ |\ /| |__ __||| | | || .-' | |/ / \ \_/ )/
(_) / /__\ \ |(\ / | )| | | `-' | | `-. | | / __ \ (_)
| | | __ | (_)\/ | (_) | | .-. | | .-' | | \ |__| ) (
| | | | |)| | \ / | | | | | |)| | `--. | |) \ | |
`-' |_| (_) | |\/| | `-' /( (_)/( __.' |((_)-' /(_|
'-' '-' (__) (__) (_) (__)

Share this post


Link to post
Share on other sites
Guest
This topic is now closed to further replies.

  • Similar Content

    • By plankton
      While IsArray(PixelSearch(100, 100, 300, 300, 0xffffff))     Send("{ESC}")     Sleep(1000) WEnd  MsgBox(0,"Loop exited","") Hi, above is my function that will execute ESC button when white color is present in specific area which is color 0xffffff.
      But how do I do the opposite like when white color is not present in that specific area? Like this below code which gives me error
       
      While IsArray(PixelSearch(100, 100, 300, 300, <>0xffffff))     Send("{ESC}")     Sleep(1000) WEnd  MsgBox(0,"Loop exited","")  
       
    • By plankton
      Hi I want it to search for a specific color in certain area then excute the loop which presses ESC button and stop the loop when the color no longer present in that specific area.  Here is the example of my code. But it doesnt stop when color is disappeared.
       
      Pixelsearch(511, 455, 678, 501, 0xFFFFFF)
      If Not  @Error Then
      While 1
      Sleep(1000)
      Send("{ESC}")
      Pixelsearch(511, 455, 678, 501, 0xFFFFFF)
      If @Error Then Exitloop
       
    • By Borges
      Sorry if I posted in wrong section but...
      how can I do something like that?
       
      If PixelSearch(660, 30, 670, 38, 0x242424, 0 , 1) <> @error Then
          Send("{F3}")
          Sleep(200)
       ElseIf PixelSearch(800, 30, 810, 38, 0x242424, 0 , 1) <> @error Then
          Send("{F4}")
          Sleep(200)
       EndIf
       
    • By Daka
      I find it very weird:
      if I run like this:
           Local $aCoord = PixelSearch($posX, $posY, $sizeX, $sizeY, '0xFF455E')
      works fine!
      If I run like this:
          Local $metaColor1 = '0xFF455E' or like this Local $metaColor1 = "0xFF455E" or Local $metaColor1 = "'0xFF455E'"
          Local $aCoord = PixelSearch($posX, $posY, $sizeX, $sizeY, $color)
      it doesn't want to work! So something with variable is not working and yes if I print it out like this:
      ConsoleWrite(@LF & $posX & ":"& $posY & ":"& $sizeX & ":" & $sizeY & ":" & $color&@LF)
      771:80:833:151:0xFF455E

      So I dont see the problem, maybe some of you people?
    • By squidol
      I need help about pixel search. The problem with the script below is that PixelSearch does not continue on the coordinates where it has stopped.
      When the first pixelsearch finds the 1st pixel, it should move the mouse over it and new pixels would appear just like hovering over menus. Then upon hover, there would be another PixelSearch to see if the second red pixel is found. If not found, then it should resume the first PixelSearch instead of starting from left to right again. 
      For example we are doing a pixelsearch on two straight lines with coordinates  [x,y]  :
      [0,0] [1,0] [2,0]
      [1,0] [1,1] [1,2]
      Pixelsearch finds the coordinate [1,0] matching our color. So it checks the pixel just below it which is [1,1] to see if it is color red. If not red then it should continue searching starting on coordinates [2,0] instead of going back to [0,0]
      Local $bflag = False Do     ToolTip("finding..",0,0,"")     Sleep(500)     $var = PixelSearch(591, 169, 1365, 740, 0x464950,50) ; look for initial pixel     If Not @error Then ;         MouseMove($var[0],$var[1],0) ;move on the button to show new selections, new pixels         sleep(1000)         ;search for the red pixel on an area above the first pixel coords which was          ;generated when mouse cursor was hovered on the first pixel found.         $redpixel = PixelSearch($var[0]-50,$var[1]-50,$var[0]+50,$var[1]+50,0xFF0048)          If Not @error Then ; Found the 2nd pixel                 ToolTip("found...",0,0,"")             $bflag = True          EndIf     EndIf Until $bflag I can pay 50USD through Paypal for a working solution. thanks   
×
×
  • Create New...