QLineEdit and QComboBox have unrelated behavior - c++11

I have a user interface with a lot of controls. However I have a problem with a QLineEdit and a QComboBox that are not responding properly.
I am basically converting from pixel measurements to millimeters/centimeters/decimeters and meters with a QComboBox and showing the result on a QLineEdit.
For the conversion table I used this page.
When I choose fromPixelToMillimeters() it does the conversion, but when I choose fromPixelToCentimeters() I think it is using the present value after the first conversion of fromPixelToMillimeters(). And if I go back choosing fromPixelToMillimeters() I get a different result too. This happens continuously, I get different measures each time.
See the code below:
void MainWindow::on_cBoxMeasures_currentIndexChanged(const QString &arg1)
{
if(arg1 == "Select Conversion(s)") {
return ui->leftLineEditDist->setText(QString("%1").arg(ui->leftLineEditDist->text().toDouble()));
} else if(arg1 == "pixel") {
return ui->leftLineEditDist->setText(QString("%1").arg(ui->leftLineEditDist->text().toDouble()));
} else if(arg1 == "mm") {
return fromPixelToMillimeters();
} else if(arg1 == "dm") {
return fromPixelToDecimeters();
} else if(arg1 == "cm") {
return fromPixelToCentimeters();
} else if(arg1 == "m") {
return fromPixelToMeters();
}
}
void MainWindow::fromPixelToMillimeters()
{
double mm = ui->leftLineEditDist->text().toDouble();
double dpi = 300;
double totalDistanceInMillimeter = (mm*25.4)/dpi;
ui->leftLineEditDist->setText(QString("%1").arg(totalDistanceInMillimeter));
ui->leftLineEditDist->show();
}
void MainWindow::fromPixelToCentimeters()
{
double mm = ui->leftLineEditDist->text().toDouble();
double dpi = 300;
double totalDistanceInCm = ((mm*25.4)/dpi)*0.1;
ui->leftLineEditDist->setText(QString("%1").arg(totalDistanceInCm));
ui->leftLineEditDist->show();
}
void MainWindow::fromPixelToDecimeters()
{
double mm = ui->leftLineEditDist->text().toDouble();
double dpi = 300;
double totalDistanceInDcm = ((mm*25.4)/dpi)*0.01;
ui->leftLineEditDist->setText(QString("%1").arg(totalDistanceInDcm));
ui->leftLineEditDist->show();
}
void MainWindow::fromPixelToMeters()
{
double mm = ui->leftLineEditDist->text().toDouble();
double dpi = 300;
double totalDistanceInM = ((mm*25.4)/dpi)*0.001;
ui->leftLineEditDist->setText(QString("%1").arg(totalDistanceInM));
ui->leftLineEditDist->show();
}
void MainWindow::on_cBoxMeasures_currentIndexChanged(int index)
{
switch (index) {
case(0):
break;
case(1):
break;
case(2):
fromPixelToMillimeters();
break;
case(3):
fromPixelToCentimeters();
break;
case(4):
fromPixelToDecimeters();
break;
case(5):
fromPixelToMeters();
break;
}
}
Please advise on what the problem might be.

I think these slots
on_cBoxMeasures_currentIndexChanged(const QString &arg1)
on_cBoxMeasures_currentIndexChanged(int index)
are connected the onIndexChange signal.
When the combo value will be changed, these two slots will be called simultaneously.
So that your code wont work well.
I recommend you to remove one of these slots.

Related

[eyeshot]How can I add a new Viewport into a viewer

what is the best way to add a new viewport into the viewer with the same drawing?
Regards Jürgen
You can check the Custom ViewportLayout source code sample.
Here is the code extracted from the above sample
private static void InitializeViewportsByLayoutType(Design design, viewportLayoutType layout)
{
int viewportsNumber;
switch (layout)
{
case viewportLayoutType.SingleViewport:
viewportsNumber = 1;
break;
case viewportLayoutType.TwoViewportsVertical:
case viewportLayoutType.TwoViewportsHorizontal:
viewportsNumber = 2;
break;
case viewportLayoutType.ThreeViewportsWithOneOnBottom:
case viewportLayoutType.ThreeViewportsWithOneOnLeft:
case viewportLayoutType.ThreeViewportsWithOneOnRight:
case viewportLayoutType.ThreeViewportsWithOneOnTop:
viewportsNumber = 3;
break;
case viewportLayoutType.FourViewports:
case viewportLayoutType.Stacked:
viewportsNumber = 4;
break;
default:
viewportsNumber = 1;
break;
}
if (design.Viewports.Count > viewportsNumber)
{
while (design.Viewports.Count > viewportsNumber)
design.Viewports.RemoveAt(design.Viewports.Count - 1);
}
else
{
while (design.Viewports.Count < viewportsNumber)
{
design.Viewports.Add((Viewport)design.Viewports[0].Clone());
}
}
// When changing the LayoutMode, the UpdateViewportsSizeAndLocation() method is called as well.
design.LayoutMode = layout;
}

Order closing and opening very quickly unintendedly in MQL4 when using multiple criteria with 'OR' operator

I am trying to close my trades based on 2 separate types of criteria,
Regardless of what the profit is, close the trade after 1020 seconds.
If my import value changes from -1 to 1 or vice versa, close it regardless of any other variables.
So far, my code works fine with 1 criteria, however when I add 2 if statements, MT4 does this thing where it opens and closes the trades very quickly, within every half a second, it doesn't look like its working properly.
If somebody could let me know what's making it do it, I would be grateful.
My code is below,
//Global Variables
//int Value = ReadCSVFile and get cell value(Either -1 or 1)
int Ticket;
int TicketBuy;
datetime SwitchBuy
datetime SwitchSell
void OnTick()
{
//Open Trades based on Value from CSV and if No other buy orders open
if(Value == 1){
if(getBuyOrderCount(Symbol(),magic) < 1){
Ticket == OrderSend(NULL,OP_BUY,0.01,Ask,2,0,0,NULL,magic,0,clrAliceBlue);
SwitchBuy = TimeCurrent();
}}
if(Value == (-1)){
if(SellOrderCount(Symbol(),magic) < 1){
TicketSell = OrderSend(NULL,OP_SELL,0.01,Bid,2,0,0,NULL,magic,0,clrAliceBlue);
SwitchSell = TimeCurrent();
}}
//Close Trades based on value in CSV file changing
if(Ticket > 0){
if(Value == (-1)||(TimeCurrent()>(SwitchBuy+60))){
CloseAllTradesBuy();
Ticket = 0;
Alert("Buy Trade Closed Because Probabilities Changed to -1!");
}
}
if(TicketSell > 0){
if(Value == 1||(TimeCurrent()>(SwitchBuy+60))){
CloseAllTradesSell();
TicketSell = 0;
Alert("Sell Trade Closed Because Probabilities Changed to 1!");
}
}
//Second Independent Criteria
if((SwitchBuy+1020) < TimeCurrent()){
if(OrderType() == OP_BUY){
CloseAllTradesBuy();
}
}
if((SwitchSell+1020) < TimeCurrent()){
if(OrderType() == OP_SELL){
CloseAllTradesSell();
}
}
}
//Functions to Close Trades
double CloseAllTradesBuy(){
for (int i =OrdersTotal(); i>=0;i--)
{
if(OrderSelect(i,SELECT_BY_POS)==true)
if(OrderType()==OP_BUY)
if (OrderSymbol()==Symbol())
{
OrderClose(Ticket,OrderLots(),MarketInfo(OrderSymbol(),MODE_BID),5,clrRed);
}
}
}
double CloseAllTradesSell(){
for (int i =OrdersTotal(); i>=0;i--)
{
if(OrderSelect(i,SELECT_BY_POS)==true)
if(OrderType()==OP_SELL)
if (OrderSymbol()==Symbol())
{
OrderClose(TicketSell,OrderLots(),MarketInfo(OrderSymbol(),MODE_ASK),5,clrRed);
}
}
}
change this code of close orders :
//Functions to Close Trades
double CloseAllTradesBuy(){
for (int i =OrdersTotal()-1; i>=0;i--)
{
if(OrderSelect(i,SELECT_BY_POS) && OrderType()==OP_BUY && OrderSymbol()==Symbol())
{
OrderClose(OrderTicket(),OrderLots(),MarketInfo(OrderSymbol(),MODE_BID),5,clrRed);
}
}
}
double CloseAllTradesSell(){
for (int i =OrdersTotal()-1; i>=0;i--)
{
if(OrderSelect(i,SELECT_BY_POS) && OrderType()==OP_SELL && OrderSymbol()==Symbol())
{
OrderClose(OrderTicket(),OrderLots(),MarketInfo(OrderSymbol(),MODE_ASK),5,clrRed);
}
}
}

How to change height of edit box associated with CMFCToolbarEditBoxButton

I would like to decrease the height of the edit box associated with a CMFCToolbarEditBoxButton on a CMFCToolBar.
I have been able to change successfully the height of a combo box associated with CMFCToolbarComboBoxButton by changing the font size after the ReplaceButton step in OnToolbarReset.
This approach doesn't work for CMFCToolbarEditBoxButton. (see CGuiEditBox section in the following code.)
The first code is from OnToolbarSet. I assign a font to the edit box. I even tried making the size of the font very small. It had no effect.
Next I tried to change the rectangle associated with the edit box in the toolbar's AdjustLocations method. That approach also was unsuccessful.
LRESULT CMainFrame::OnToolbarReset(WPARAM wp, LPARAM)
{
UINT uiToolBarId = (UINT)wp;
switch (uiToolBarId)
{
case IDR_TOPTOOLBAR_REG:
{
CZoomCombo ZoomCombo;
ZoomCombo.EnableWindow(TRUE);
ZoomCombo.SetDropDownHeight(300);
ZoomCombo.SetCenterVert(TRUE);
ZoomCombo.AddItem(_T(".5x"));
ZoomCombo.AddItem(_T("1x"));
ZoomCombo.AddItem(_T("2x"));
ZoomCombo.AddItem(_T("3x"));
ZoomCombo.AddItem(_T("4x"));
ZoomCombo.AddItem(_T("5x"));
ZoomCombo.AddItem(_T("6x"));
ZoomCombo.AddItem(_T("7x"));
ZoomCombo.AddItem(_T("8x"));
ZoomCombo.AddItem(_T("9x"));
ZoomCombo.AddItem(_T("10x"));
m_wndTopToolBar.ReplaceButton(IDC_ZOOMCOMBO_DUMMY, ZoomCombo);
do
{
CMFCToolBarButton* pButton = NULL;
int nZoomIndex = m_wndTopToolBar.CommandToIndex(IDC_ZOOMCOMBO);
if (nZoomIndex == -1)
break;
pButton = m_wndTopToolBar.GetButton(nZoomIndex);
if (pButton == NULL)
break;
ASSERT(pButton->IsKindOf(RUNTIME_CLASS(CMFCToolBarComboBoxButton)));
CMFCToolBarComboBoxButton* pComboButton = (CMFCToolBarComboBoxButton*)pButton;
CComboBox* pCbo = pComboButton->GetComboBox();
CEdit* pEdit = pComboButton->GetEditCtrl();
if (pCbo == NULL || pEdit == NULL)
break;
pCbo->SetFont(&m_ToolBarBtnFont);
pEdit->SetFont(&m_ToolBarBtnFont);
m_wndTopToolBar.InvalidateButton(nZoomIndex);
int nSel = GetZoomComboIndex(m_Zoom);
if (nSel >= 0)
{
pCbo->SetCurSel(nSel);
CString str;
pCbo->GetWindowText(str);
pComboButton->SetText(str);
}
} while (false);
//
CGuiEditBox GuiEditBox;
GuiEditBox.EnableWindow(TRUE);
m_wndTopToolBar.ReplaceButton(IDC_GUIEDITBOX_DUMMY, GuiEditBox);
do
{
CMFCToolBarButton* pButton = NULL;
int nGuiIndex = m_wndTopToolBar.CommandToIndex(IDC_GUIEDITBOX);
if (nGuiIndex == -1)
break;
pButton = m_wndTopToolBar.GetButton(nGuiIndex);
if (pButton == NULL)
break;
ASSERT(pButton->IsKindOf(RUNTIME_CLASS(CMFCToolBarEditBoxButton)));
CMFCToolBarEditBoxButton* pEditBoxButton = (CMFCToolBarEditBoxButton*)pButton;
CEdit* pEdit = pEditBoxButton->GetEditBox();
if (pEdit == NULL)
break;
pEdit->SetFont(&m_ToolBarBtnFont); // height of this font is much less than default
//CFont* pFont = pEdit->GetFont();
//LOGFONT lf;
//pFont->GetLogFont(&lf); // confirmed that font has been changed
m_wndTopToolBar.InvalidateButton(nGuiIndex);
} while (false);
}
break;
}
return 0;
}
//
void CMFCToolBarEx::AdjustLocations()
{
CMFCToolBar::AdjustLocations();
if (GetSafeHwnd())
{
CMFCToolBarButton* pButton = NULL;
int nGuiIndex = CommandToIndex(IDC_GUIEDITBOX);
if (nGuiIndex != -1)
{
pButton = GetButton(nGuiIndex);
if (pButton)
{
ASSERT(pButton->IsKindOf(RUNTIME_CLASS(CMFCToolBarEditBoxButton)));
CMFCToolBarEditBoxButton* pEditBoxButton = (CMFCToolBarEditBoxButton*)pButton;
CEdit* pEdit = pEditBoxButton->GetEditBox();
if (pEdit != NULL)
{
CRect rPos;
pEdit->GetRect(&rPos);
rPos.DeflateRect(0, 4);
pEdit->SetRect(rPos);
}
}
}
}
}
I investigated the source code for afxtoolbareditboxbutton.cpp and saw that the height of the edit box is being set in the OnMove method by the following line
int cy = GetGlobalData()->GetTextHeight();
I changed that line in a subclass of CMFCToolBarEditBoxButton to resolve my problem.

How to correct loop counters for maze algorithm?

I have figured out how to move my character around the maze using the algorithm I have written, but the count is not figuring correctly. At the end of each row my character moves up and down several times until the count reaches the specified number to exit the loop, then the character moves along the next row down until it reaches the other side and repeats the moving up and down until the count reaches the specified number again. Can anyone help me find why my count keeps getting off? The algorithm and the maze class I am calling from is listed below.
public class P4 {
public static void main(String[] args) {
// Create maze
String fileName = args[3];
Maze maze = new Maze(fileName);
System.out.println("Maze name: " + fileName);
// Get dimensions
int mazeWidth = maze.getWidth();
int mazeHeight = maze.getHeight();
// Print maze size
System.out.println("Maze width: " + mazeWidth);
System.out.println("Maze height: " + mazeHeight);
int r = 0;
int c = 0;
// Move commands
while (true){
for (c = 0; c <= mazeWidth; c++){
if (maze.moveRight()){
maze.isDone();
c++;
}
if (maze.isDone() == true){
System.exit(1);
}
if (maze.moveRight() == false && c != mazeWidth){
maze.moveDown();
maze.moveRight();
maze.moveRight();
maze.moveUp();
c++;
}
}
for (r = 0; r % 2 == 0; r++){
maze.moveDown();
maze.isDone();
if (maze.isDone() == true){
System.exit(1);
}
}
for (c = mazeWidth; c >= 0; c--){
if (maze.moveLeft()){
c--;
maze.isDone();
System.out.println(c);
}
if (maze.isDone() == true){
System.exit(1);
}
if (maze.moveLeft() == false && c != 0){
maze.moveDown();
maze.moveLeft();
maze.moveLeft();
maze.moveUp();
c--;
}
}
for (r = 1; r % 2 != 0; r++){
maze.moveDown();
maze.isDone();
if (maze.isDone() == true){
System.exit(1);
}
}
}
}
}
public class Maze {
// Maze variables
private char mazeData[][];
private int mazeHeight, mazeWidth;
private int finalRow, finalCol;
int currRow;
private int currCol;
private int prevRow = -1;
private int prevCol = -1;
// User interface
private JFrame frame;
private JPanel panel;
private Image java, student, success, donotpass;
private ArrayList<JButton> buttons;
// Maze constructor
public Maze(String fileName) {
// Read maze
readMaze(fileName);
// Graphics setup
setupGraphics();
}
// Get height
public int getHeight() {
return mazeHeight;
}
// Get width
public int getWidth() {
return mazeWidth;
}
// Move right
public boolean moveRight() {
// Legal move?
if (currCol + 1 < mazeWidth) {
// Do not pass?
if (mazeData[currRow][currCol + 1] != 'D')
{
currCol++;
redraw(true);
return true;
}
}
return false;
}
// Move left
public boolean moveLeft() {
// Legal move?
if (currCol - 1 >= 0) {
// Do not pass?
if (mazeData[currRow][currCol - 1] != 'D')
{
currCol--;
redraw(true);
return true;
}
}
return false;
}
// Move up
public boolean moveUp() {
// Legal move?
if (currRow - 1 >= 0) {
// Do not pass?
if (mazeData[currRow - 1][currCol] != 'D')
{
currRow--;
redraw(true);
return true;
}
}
return false;
}
// Move down
public boolean moveDown() {
// Legal move?
if (currRow + 1 < mazeHeight) {
// Do not pass?
if (mazeData[currRow + 1][currCol] != 'D')
{
currRow++;
redraw(true);
return true;
}
}
return false;
}
public boolean isDone() {
// Maze solved?
if ((currRow == finalRow) && (currCol == finalCol))
return true;
else
return false;
}
private void redraw(boolean print) {
// Wait for awhile
try {
Thread.sleep(500);
} catch (InterruptedException ex) {
Thread.currentThread().interrupt();
}
if (print)
System.out.println("Moved to row " + currRow + ", column " + currCol);
// Compute index and remove icon
int index = (prevRow * mazeWidth) + prevCol;
if ((prevRow >= 0) && (prevCol >= 0)) {
buttons.get(index).setIcon(null);
}
// Compute index and add icon
index = (currRow * mazeWidth) + currCol;
if ((currRow == finalRow) && (currCol == finalCol))
buttons.get(index).setIcon(new ImageIcon(success));
else
buttons.get(index).setIcon(new ImageIcon(student));
// Store previous location
prevRow = currRow;
prevCol = currCol;
}
// Set button
private void setButton(JButton button, int row, int col) {
if (mazeData[row][col] == 'S') {
button.setIcon(new ImageIcon(student));
currRow = row;
currCol = col;
} else if (mazeData[row][col] == 'J') {
button.setIcon(new ImageIcon(java));
finalRow = row;
finalCol = col;
} else if (mazeData[row][col] == 'D') {
button.setIcon(new ImageIcon(donotpass));
}
}
// Read maze
private void readMaze(String filename) {
try {
// Open file
Scanner scan = new Scanner(new File(filename));
// Read numbers
mazeHeight = scan.nextInt();
mazeWidth = scan.nextInt();
// Allocate maze
mazeData = new char[mazeHeight][mazeWidth];
// Read maze
for (int row = 0; row < mazeHeight; row++) {
// Read line
String line = scan.next();
for (int col = 0; col < mazeWidth; col++) {
mazeData[row][col] = line.charAt(col);
}
}
// Close file
scan.close();
} catch (IOException e) {
System.out.println("Cannot read maze: " + filename);
System.exit(0);
}
}
// Setup graphics
private void setupGraphics() {
// Create grid
frame = new JFrame();
panel = new JPanel();
panel.setLayout(new GridLayout(mazeHeight, mazeWidth, 0, 0));
frame.add(Box.createRigidArea(new Dimension(0, 5)), BorderLayout.NORTH);
frame.add(panel, BorderLayout.CENTER);
// Look and feel
try {
UIManager.setLookAndFeel(UIManager.getCrossPlatformLookAndFeelClassName());
} catch (Exception e) {
e.printStackTrace();
}
// Configure window
frame.setSize(mazeWidth * 100, mazeHeight * 100);
frame.setTitle("Maze");
frame.setResizable(false);
frame.setLocationRelativeTo(null);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setAlwaysOnTop(true);
// Load and scale images
ImageIcon icon0 = new ImageIcon("Java.jpg");
Image image0 = icon0.getImage();
java = image0.getScaledInstance(100, 100, Image.SCALE_DEFAULT);
ImageIcon icon1 = new ImageIcon("Student.jpg");
Image image1 = icon1.getImage();
student = image1.getScaledInstance(100, 100, Image.SCALE_DEFAULT);
ImageIcon icon2 = new ImageIcon("Success.jpg");
Image image2 = icon2.getImage();
success = image2.getScaledInstance(100, 100, Image.SCALE_DEFAULT);
ImageIcon icon3 = new ImageIcon("DoNotPass.jpg");
Image image3 = icon3.getImage();
donotpass = image3.getScaledInstance(100, 100, Image.SCALE_DEFAULT);
// Build panel of buttons
buttons = new ArrayList<JButton>();
for (int row = 0; row < mazeHeight; row++) {
for (int col = 0; col < mazeWidth; col++) {
// Initialize and add button
JButton button = new JButton();
Border border = new LineBorder(Color.darkGray, 4);
button.setOpaque(true);
button.setBackground(Color.gray);
button.setBorder(border);
setButton(button, row, col);
panel.add(button);
buttons.add(button);
}
}
// Show window
redraw(false);
frame.setVisible(true);
}
}
One error I can see in your code is that you're incrementing your c counter more often than you should. You start with it managed by your for loop, which means that it will be incremented (or decremented, for the leftward moving version) at the end of each pass through the loop. However, you also increment it an additional time in two of your if statements. That means that c might increase by two or three on a single pass through the loop, which is probably not what you intend.
Furthermore, the count doesn't necessarily have anything obvious to do with the number of moves you make. The loop code will always increase it by one, even if you're repeatedly trying to move through an impassible wall.
I don't really understand what your algorithm is supposed to be, so I don't have any detailed advice for how to fix your code.
One suggestion I have though is that you probably don't ever want to be calling methods on your Maze class without paying attention to their return values. You have a bunch of places where you call isDone but ignore the return value, which doesn't make any sense. Similarly, you should always be checking the return values from your moveX calls, to see if the move was successful or not. Otherwise you may just blunder around a bunch, without your code having any clue where you are in the maze.

In Selenium, how to compare images?

As i have been asked to automate our Company's website using Selenium Automation tooL.
But i am new to Selenium tool to proceed with, but i have learnt the basics of Selenium IDE and RC. But i am very much confused with how to compare actual and original images as we usually do in other automation tools. How do we come to a result that there bug in the website? Its obviously through image comparison but i wonder as selenium is one of the very popular tools but it doesn't have image comparing option. On the other hand i doubt whether my way of proceeding with the automation process is correct! Could somebody please help me out..
Thanks in Advance!!
Sanjay S
I had simillar task. I needed to compare more than 3000 images on a WebPage.
First of all I scrolled page to load all images:
public void compareImage() throws InterruptedException {
driver.get(baseUrl);
driver.manage().window().maximize();
JavascriptExecutor executor = (JavascriptExecutor) driver;
Long previousHeight;
Long currentHeight;
do {
previousHeight = (Long) executor.executeScript("return document.documentElement.scrollHeight");
executor.executeScript("window.scrollBy(0, document.documentElement.scrollHeight)");
Thread.sleep(500);
currentHeight = (Long) executor.executeScript("return document.documentElement.scrollHeight");
} while (Long.compare(previousHeight, currentHeight) != 0);
after I compared size of all images with first image(or you can just write size):
List<WebElement> images = driver.findElements(By.cssSelector("img[class='playable']"));
List<String> errors = new LinkedList<>();
int imgWidth, imgHeight, elWidth, elHeight;
int imgNum = 0;
imgWidth = images.get(0).getSize().getWidth();
imgHeight = images.get(0).getSize().getHeight();
for (WebElement el : images) {
imgNum++;
elWidth = el.getSize().getWidth();
elHeight = el.getSize().getHeight();
if (imgWidth != elWidth || imgHeight != elHeight) {
errors.add(String.format("Picture # %d has incorrect size (%d : %d) px"
, imgNum, elWidth, elHeight));
}
}
for (String str : errors)
System.out.println(str);
if (errors.size() == 0)
System.out.println("All images have the same size");
}
Since you mention knowledge about Selenium RC, you can easily extend Selenium's capability using a library for your chosen programming language. For instance, in Java you can use the PixelGrabber class for comparing two images and assert their match.
imagemagick and imagediff are also two good tools to use for image matching. You would require Selenium RC and a programming language knowledge to work with it.
Image comparison on C#. To get exact results I recommend to disable anti aliasing browser feature before taking screenshots, otherwise pixels each time are a little bit different drawn. For example HTML canvas element options.AddArgument("disable-canvas-aa");
private static bool ImageCompare(Bitmap bmp1, Bitmap bmp2, Double TolerasnceInPercent)
{
bool equals = true;
bool flag = true; //Inner loop isn't broken
//Test to see if we have the same size of image
if (bmp1.Size == bmp2.Size)
{
for (int x = 0; x < bmp1.Width; ++x)
{
for (int y = 0; y < bmp1.Height; ++y)
{
Color Bitmap1 = bmp1.GetPixel(x, y);
Color Bitmap2 = bmp2.GetPixel(x, y);
if (Bitmap1.A != Bitmap2.A)
{
if (!CalculateTolerance(Bitmap1.A, Bitmap2.A, TolerasnceInPercent))
{
flag = false;
equals = false;
break;
}
}
if (Bitmap1.R != Bitmap2.R)
{
if (!CalculateTolerance(Bitmap1.R, Bitmap2.R, TolerasnceInPercent))
{
flag = false;
equals = false;
break;
}
}
if (Bitmap1.G != Bitmap2.G)
{
if (!CalculateTolerance(Bitmap1.G, Bitmap2.G, TolerasnceInPercent))
{
flag = false;
equals = false;
break;
}
}
if (Bitmap1.B != Bitmap2.B)
{
if (!CalculateTolerance(Bitmap1.B, Bitmap2.B, TolerasnceInPercent))
{
flag = false;
equals = false;
break;
}
}
}
if (!flag)
{
break;
}
}
}
else
{
equals = false;
}
return equals;
}
This C# function calculates tolerance
private static bool CalculateTolerance(Byte FirstImagePixel, Byte SecondImagePixel, Double TolerasnceInPercent)
{
double OneHundredPercent;
double DifferencesInPix;
double DifferencesPercentage;
if (FirstImagePixel > SecondImagePixel)
{
OneHundredPercent = FirstImagePixel;
}
else
{
OneHundredPercent = SecondImagePixel;
}
if (FirstImagePixel > SecondImagePixel)
{
DifferencesInPix = FirstImagePixel - SecondImagePixel;
}
else
{
DifferencesInPix = SecondImagePixel - FirstImagePixel;
}
DifferencesPercentage = (DifferencesInPix * 100) / OneHundredPercent;
DifferencesPercentage = Math.Round(DifferencesPercentage, 2);
if (DifferencesPercentage > TolerasnceInPercent)
{
return false;
}
return true;
}

Resources