Page 1 of 2 12 Last
  • Jump to page:
    #1
  1. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Dec 2012
    Posts
    16
    Rep Power
    0

    Programming photoshop difference filter


    Hi:
    I'm gonna need some steady help over the next 3 weeks, if anyone wishes to be in on this for the long hall. I have to program a version of the Photoshop Difference Filter. To be honest, I'm not sure where to start with it. I guess I need to look at some examples of similar filtering programs, find out how they are working, etc.
    Any starting tips appreciated
    Thank you
  2. #2
  3. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Oct 2012
    Posts
    187
    Rep Power
    82
    Any starting tips appreciated
    Can we assume that you've already downloaded the Adobe Photoshop SDK ?
    Last edited by BobS0327; December 18th, 2012 at 07:38 AM.
  4. #3
  5. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Dec 2012
    Posts
    16
    Rep Power
    0

    Unhappy photoshop SDK


    Nope. I haven't. Didn't know about it. It says I need to use the SDK to update plug-ins to run with the 64-bit version of Photoshop. Does this mean we can see an update the source code for plug-ins, like Open Source software? I though that all the Photoshop code would be proprietary and we would not have access to it.

    I have just downloaded a trial version of CS6. I will assume I need the SDK version and download that now. What to do with it?

    thanks Bob

    P.S. Just to let you all know, this is a school project and I'm pretty much in the dark on this and not the greatest programmer, so I hope I don't annoy you with my upcoming stupidity
  6. #4
  7. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Dec 2012
    Posts
    16
    Rep Power
    0

    photoshop SDK


    ok. So I have downloaded and looked. Seems really cool. So this is like a starter pack where we can develop our own plugins to use on apps / windows / macs, etc. And anything we develop we can sell or distribute royalty free.
    There are a lot of files like header files, samples and resources to get us going, which is cool :o
    There is a lot of documentation, so I guess I need to do some reading to get the history and where it's at now.
    And I guess I should be heading toward the plug-in module for filters which will maybe give the structure of the program for creating filters?
  8. #5
  9. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Oct 2012
    Posts
    187
    Rep Power
    82
    P.S. Just to let you all know, this is a school project and I'm pretty much in the dark on this and not the greatest programmer, so I hope I don't annoy you with my upcoming stupidity
    Can you post the detailed requirements of this school project?
  10. #6
  11. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Dec 2012
    Posts
    16
    Rep Power
    0

    aligning and differencing images


    I don't think I wanna use SDK and Photoshop, just do it in C. I need to import a series of images used as Base images. These are considered good and the objects in the images have no faults / defects / are not missing, etc. Then another series of images taken at similar, but not exactly the same positions to the originals need to be imported. The difference in locations between the database images and the second series needs to be automatically corrected and then the difference / subtraction needs to be performed so that any differences can be clearly shown. A bounding box with some data about the type of defect then needs to be shown so that it is detailed and easily located in the series.
    Simple! :eek:

    I think I can just use subtraction code to show difference.
    g(x,y) = f(x,y) - h(x,y)
    maybe
    Last edited by defunktlemon; December 18th, 2012 at 04:03 PM. Reason: forgot code
  12. #7
  13. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Oct 2012
    Posts
    187
    Rep Power
    82
    What's the format of your images? Jpeg, PNG, BMP etc? If bitmap, are they 8, 24, 32 bits?

    Also, are you allowed to use any open source imaging packages for your assignment?

    Finally, here is a link to sample Win32 C code dealing with bitmap images for your review. It'll give you some idea of the coding you may have to do.
  14. #8
  15. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Dec 2012
    Posts
    16
    Rep Power
    0
    wow! that's a lotta code. I'm currently an improving code-retard, with some way to go to be considered a good coder. I will go through it and try to make some sense of it, at least what I can.
    My captured images are in .jpeg format.

    open source imaging packages - maybe but time is short and if you're suggesting OpenCV the learning curve would be too high I think.
  16. #9
  17. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Dec 2012
    Posts
    16
    Rep Power
    0
    I think I would like to develop this bit by bit. So, I guess I need to look at all the processes I need to complete and tackle them one by one in separate functions. So first,
    1. I need to load the images into C and probably turn them into binary / black & white. This will reduce the file size which is good.
    2. I need to align the images
    3. I need to difference the images and show the new image
    4. I need to locate the center of the difference object and create a bounding box around them
    5. The objects once located need to be detailed
    So, for 1, will I need to import all the image pixel values into an array / matrix?
  18. #10
  19. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Oct 2012
    Posts
    187
    Rep Power
    82
    1. I need to load the images into C and probably turn them into binary / black & white. This will reduce the file size which is good.
    You'll have to create a HBITMAP which is a handle to a bitmap from your JPEG image. Guidelines to do this are as follows:

    Open the JPEG in rb Read Binary mode using fopen
    Allocate heap memory for the full size of the file
    Create a CreateStreamOnHGlobal to store the stream contents.
    Use OleLoadPicture to load the JPEG image.
    OleLoadPicture returns the fifth parameter which is used to maintain the object in memory using an Ipicture pointer. You must get this pointer to get the handle of the HBITMAP
    Then you must use CopyImage to copy the JPEG image into the HBITMAP.
    Release the OleLoadPicture pointer and return the HBITMAP handle back to the calling function since it will be used in your next function to serialize the pixel data in your JPEG images in order to make a comparison of pixels.

    I'm not sure if it's a good idea to convert the image to black/white since this introduces an additional level of complexity. Although it's possible to do a lossless conversion, writing the additional code may be really time consuming in light of your three week deadline. File size is not a serious issue. IMHO, the real issue is the overall complexity of the project.

    Bottom line, use the KIS (Keep It Simple) method.

    Finally, can you post a sample of your base image and a image that is to be compared against the base image?
    Last edited by BobS0327; December 19th, 2012 at 12:19 AM.
  20. #11
  21. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Dec 2012
    Posts
    16
    Rep Power
    0
    Hi Bob. Thanks for the reply. I am considering the complexity of this and what is the best route to take. What would you advise on that point?
    The project has us using a model railway we created to take photos of. I am posting an example of the model made. The first is where all the model clamps are ok. The second photo shows some of the clamps broken or missing. The last is the photoshop image using the difference filter. The interesting thing about that is that when I used the subtraction filter the result was poor in comparison to the difference filter. Not sure why excect maybe that the subtraction filter leaves positive numbers whereas the difference leaves negative. Just a guess.

    Good Image


    Bad Image


    Differenced Image





    Originally Posted by BobS0327
    You'll have to create a HBITMAP which is a handle to a bitmap from your JPEG image. Guidelines to do this are as follows:

    Open the JPEG in rb Read Binary mode using fopen
    Allocate heap memory for the full size of the file
    Create a CreateStreamOnHGlobal to store the stream contents.
    Use OleLoadPicture to load the JPEG image.
    OleLoadPicture returns the fifth parameter which is used to maintain the object in memory using an Ipicture pointer. You must get this pointer to get the handle of the HBITMAP
    Then you must use CopyImage to copy the JPEG image into the HBITMAP.
    Release the OleLoadPicture pointer and return the HBITMAP handle back to the calling function since it will be used in your next function to serialize the pixel data in your JPEG images in order to make a comparison of pixels.

    I'm not sure if it's a good idea to convert the image to black/white since this introduces an additional level of complexity. Although it's possible to do a lossless conversion, writing the additional code may be really time consuming in light of your three week deadline. File size is not a serious issue. IMHO, the real issue is the overall complexity of the project.

    Bottom line, use the KIS (Keep It Simple) method.

    Finally, can you post a sample of your base image and a image that is to be compared against the base image?
  22. #12
  23. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Dec 2012
    Posts
    16
    Rep Power
    0
    I have found this coding example to read and display bitmap images. These files can be changed to bitmap images as file types are not a requirement for the project. I can just use this or another example in my code and reference it in the report / code. Otherwise I think I will be attempting too much to write all from scratch given my lack of experience. The coding I need to be responsible for and understand at this stage is the differencing / bounding box / message display sections. I guess I can use this code and put the rest within it, right?

    http://xoax.net/cpp/crs/win32/lessons/Lesson9/
  24. #13
  25. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Oct 2012
    Posts
    187
    Rep Power
    82
    Originally Posted by defunktlemon
    I have found this coding example to read and display bitmap images. These files can be changed to bitmap images as file types are not a requirement for the project. I can just use this or another example in my code and reference it in the report / code. Otherwise I think I will be attempting too much to write all from scratch given my lack of experience. The coding I need to be responsible for and understand at this stage is the differencing / bounding box / message display sections. I guess I can use this code and put the rest within it, right?

    http://xoax.net/cpp/crs/win32/lessons/Lesson9/
    Nope. Unfortunately, it won't work. Your images are JPEG images. This code loads and displays BITMAP images. Thus, you'll have to follow my guidelines in the previous post and create a HBITMAP handle from your JPEG image and then load and display the image.

    Gimme a few hours and I'll rewrite that code to display a JPEG image. This will be my freebie to you.

    But please understand that writing Win32 C code is not a easy undertaking.

    I'm coding your assignment in parallel with you so that I don't post any misinformation and the Win32 coding will get more complex as you near the completion of the project. Loading the JPEG is really the "piece of cake" part of this assignment.
  26. #14
  27. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Dec 2012
    Posts
    16
    Rep Power
    0
    Wow! That's a very generous and appreciated offer Bob. Thank you very much. I'm curious though, why does this need to be done in Win32 C code. Can the same thing be done just as easy or easier in Visual Studio C++ or C# or just C? I'm not familiar with Win32 and just don't know about it which scares me. Is it a framework? A bunch of header files like OpenCV? Or a type of language? Sorry for sounding so dumb. I did warn you :)
    I'm familiar with writing very basic programs in Visual Studio only using C and C++.
  28. #15
  29. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Oct 2012
    Posts
    187
    Rep Power
    82
    Originally Posted by defunktlemon
    Wow! That's a very generous and appreciated offer Bob. Thank you very much. I'm curious though, why does this need to be done in Win32 C code. Can the same thing be done just as easy or easier in Visual Studio C++ or C# or just C? I'm not familiar with Win32 and just don't know about it which scares me. Is it a framework? A bunch of header files like OpenCV? Or a type of language? Sorry for sounding so dumb. I did warn you :)
    I'm familiar with writing very basic programs in Visual Studio only using C and C++.
    It doesn't necessarily have to be written in Win32 C code. It can be written in a number of different ways which include using C# or C++. You've got to look at this task from your perspective. What do you feel most comfortable with? Choose an option that feels least intimidating to you and go with it. Keep in mind that you have a three week deadline. So, you should feel "warm and fuzzy" about any option that your choose to complete this task. That is, the option selected will allow you to easily complete the task in the given time frame.

    I chose Win 32 C since you didn't want to use the Photoshop SDK nor any libraries such as OpenCV. Thus, I was limited to Win32 C since a Graphical User Interface (GUI) is really needed for this assignment. The Win32 API's provide the GUI. Win32 code can also be written in C++ but it just adds more complexity to the assignment without any additional benefits, IMHO.

    C# (.Net framework) can also be very easily used to complete this assignment in a timely fashion.

    Bottom line is that you have to chose the best tool to easily complete your assignment on time.

    But anyway, the following code will load a JPEG image. I hard coded the path to the image. So, you may have to change the path. Also, I created the image window with static X,Y metrics. These metrics may have to be changed to fully display the image. Finally, the image is loaded and displayed by clicking on the About option in the menu.

    // Win32Lesson1.cpp : Defines the entry point for the application.
    //

    Code:
    #include "stdafx.h"
    #include "Win32Lesson1.h"
    // Following three header files needed to load JPEG image
    #include <oleCtl.h>
    #include <Ole2.h>
    #include <stdio.h>
    
    // Following two globals needed to load JPEG image
    HBITMAP hb;
    HWND hChild1;
    
    #define MAX_LOADSTRING 100
    
    // Global Variables:
    HINSTANCE hInst;								// current instance
    TCHAR szTitle[MAX_LOADSTRING];					// The title bar text
    TCHAR szWindowClass[MAX_LOADSTRING];			// the main window class name
    
    // Forward declarations of functions included in this code module:
    ATOM				MyRegisterClass(HINSTANCE hInstance);
    BOOL				InitInstance(HINSTANCE, int);
    LRESULT CALLBACK	WndProc(HWND, UINT, WPARAM, LPARAM);
    INT_PTR CALLBACK	About(HWND, UINT, WPARAM, LPARAM);
    
    int APIENTRY _tWinMain(HINSTANCE hInstance,
                         HINSTANCE hPrevInstance,
                         LPTSTR    lpCmdLine,
                         int       nCmdShow)
    {
    	UNREFERENCED_PARAMETER(hPrevInstance);
    	UNREFERENCED_PARAMETER(lpCmdLine);
    
     	// TODO: Place code here.
    	MSG msg;
    	HACCEL hAccelTable;
    
    	// Initialize global strings
    	LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
    	LoadString(hInstance, IDC_WIN32LESSON1, szWindowClass, MAX_LOADSTRING);
    	MyRegisterClass(hInstance);
    
    	// Perform application initialization:
    	if (!InitInstance (hInstance, nCmdShow))
    	{
    		return FALSE;
    	}
    
    	hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_WIN32LESSON1));
    
    	// Main message loop:
    	while (GetMessage(&msg, NULL, 0, 0))
    	{
    		if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
    		{
    			TranslateMessage(&msg);
    			DispatchMessage(&msg);
    		}
    	}
    
    	return (int) msg.wParam;
    }
    
    
    
    //
    //  FUNCTION: MyRegisterClass()
    //
    //  PURPOSE: Registers the window class.
    //
    //  COMMENTS:
    //
    //    This function and its usage are only necessary if you want this code
    //    to be compatible with Win32 systems prior to the 'RegisterClassEx'
    //    function that was added to Windows 95. It is important to call this function
    //    so that the application will get 'well formed' small icons associated
    //    with it.
    //
    ATOM MyRegisterClass(HINSTANCE hInstance)
    {
    	WNDCLASSEX wcex;
    
    	wcex.cbSize = sizeof(WNDCLASSEX);
    
    	wcex.style			= CS_HREDRAW | CS_VREDRAW;
    	wcex.lpfnWndProc	= WndProc;
    	wcex.cbClsExtra		= 0;
    	wcex.cbWndExtra		= 0;
    	wcex.hInstance		= hInstance;
    	wcex.hIcon			= LoadIcon(hInstance, MAKEINTRESOURCE(IDI_WIN32LESSON1));
    	wcex.hCursor		= LoadCursor(NULL, IDC_ARROW);
    	wcex.hbrBackground	= (HBRUSH)(COLOR_WINDOW+1);
    	wcex.lpszMenuName	= MAKEINTRESOURCE(IDC_WIN32LESSON1);
    	wcex.lpszClassName	= szWindowClass;
    	wcex.hIconSm		= LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));
    
    	return RegisterClassEx(&wcex);
    }
    
    //
    //   FUNCTION: InitInstance(HINSTANCE, int)
    //
    //   PURPOSE: Saves instance handle and creates main window
    //
    //   COMMENTS:
    //
    //        In this function, we save the instance handle in a global variable and
    //        create and display the main program window.
    //
    BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
    {
       HWND hWnd;
    
       hInst = hInstance; // Store instance handle in our global variable
    
       hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
          CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);
       // Child window needed to load JPEG image
       hChild1 = CreateWindow(L"STATIC", NULL, WS_VISIBLE | WS_CHILD | SS_BITMAP,
    					100, 100, 200, 200, hWnd, (HMENU)10000, hInst, NULL);
    
       if (!hWnd)
       {
          return FALSE;
       }
    
       ShowWindow(hWnd, nCmdShow);
       UpdateWindow(hWnd);
    
       return TRUE;
    }
    // Generate HBITMAP handle form JPEG image
    HBITMAP ConvertJPEGImage2HBITMAP(char* szFileName)
    {
    	// Use IPicture for accessing JPEG file
    	IPicture* picture;
    	IStream* stream = NULL;
    	HGLOBAL hGlobal;
    	void* tempPointer;
    	FILE* fp;
    
    
    	// Read file in memory
    	fp = fopen(szFileName,"rb");
    	if (!fp)
    		return NULL;
    
    	fseek(fp,0,SEEK_END);
    	int fs = ftell(fp);
    	fseek(fp,0,SEEK_SET);
    	hGlobal = GlobalAlloc(GPTR,fs);
    	if (!hGlobal)
    	{
    		fclose(fp);
    		return NULL;
    	}
    	tempPointer = (void*)hGlobal;
    	fread(tempPointer,1,fs,fp);
    	fclose(fp);
    	
    	CreateStreamOnHGlobal(hGlobal,false,&stream);
    	if (!stream)
    	{
    		GlobalFree(hGlobal);
    		return NULL;
    	}
    
    	OleLoadPicture(stream,0,false,IID_IPicture,(void**)&picture);
    
    	if (!picture)
    	{
    		stream->Release();
    		GlobalFree(hGlobal);
    		return NULL;
    	}
    	
    	HBITMAP hBitmap = 0;
    	picture->get_Handle((unsigned int*)&hBitmap);
    
    	// Copy the image. Necessary, because upon p's release,
    	// the handle is destroyed.
    	HBITMAP hBBitmap = (HBITMAP)CopyImage(hBitmap,IMAGE_BITMAP,0,0,
    		LR_COPYRETURNORG);
    
    	picture->Release();
    	return hBBitmap;
    }
    
    bool LoadAndBlitBitmap(LPCWSTR szFileName, HDC hWinDC)
    {
    	// Load the bitmap image file
    	HBITMAP hBitmap;
    	hBitmap = (HBITMAP)::LoadImage(NULL, szFileName, IMAGE_BITMAP, 0, 0,
    		LR_LOADFROMFILE);
    	// Verify that the image was loaded
    	if (hBitmap == NULL) {
    		::MessageBox(NULL, __T("LoadImage Failed"), __T("Error"), MB_OK);
    		return false;
    	}
    
    	// Create a device context that is compatible with the window
    	HDC hLocalDC;
    	hLocalDC = ::CreateCompatibleDC(hWinDC);
    	// Verify that the device context was created
    	if (hLocalDC == NULL) {
    		::MessageBox(NULL, __T("CreateCompatibleDC Failed"), __T("Error"), MB_OK);
    		return false;
    	}
    
    	// Get the bitmap's parameters and verify the get
    	BITMAP qBitmap;
    	int iReturn = GetObject(reinterpret_cast<HGDIOBJ>(hBitmap), sizeof(BITMAP),
    		reinterpret_cast<LPVOID>(&qBitmap));
    	if (!iReturn) {
    		::MessageBox(NULL, __T("GetObject Failed"), __T("Error"), MB_OK);
    		return false;
    	}
    
    	// Select the loaded bitmap into the device context
    	HBITMAP hOldBmp = (HBITMAP)::SelectObject(hLocalDC, hBitmap);
    	if (hOldBmp == NULL) {
    		::MessageBox(NULL, __T("SelectObject Failed"), __T("Error"), MB_OK);
    		return false;
    	}
    
    	// Blit the dc which holds the bitmap onto the window's dc
    	BOOL qRetBlit = ::BitBlt(hWinDC, 0, 0, qBitmap.bmWidth, qBitmap.bmHeight,
    		hLocalDC, 0, 0, SRCCOPY);
    	if (!qRetBlit) {
    		::MessageBox(NULL, __T("Blit Failed"), __T("Error"), MB_OK);
    		return false;
    	}
    
    	// Unitialize and deallocate resources
    	::SelectObject(hLocalDC, hOldBmp);
    	::DeleteDC(hLocalDC);
    	::DeleteObject(hBitmap);
    	return true;
    }
    
    //
    //  FUNCTION: WndProc(HWND, UINT, WPARAM, LPARAM)
    //
    //  PURPOSE:  Processes messages for the main window.
    //
    //  WM_COMMAND	- process the application menu
    //  WM_PAINT	- Paint the main window
    //  WM_DESTROY	- post a quit message and return
    //
    //
    LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
    {
    	int wmId, wmEvent;
    	PAINTSTRUCT ps;
    	HDC hdc;
    
    	switch (message)
    	{
    	case WM_COMMAND:
    		wmId    = LOWORD(wParam);
    		wmEvent = HIWORD(wParam);
    		// Parse the menu selections:
    		switch (wmId)
    		{
    		case IDM_ABOUT:
    			//  Here is where I load JPEG image by clicking the About option
    			hb =ConvertJPEGImage2HBITMAP("C:/temp/tulip.jpg");
    			SendMessage(hChild1, STM_SETIMAGE, (WPARAM)IMAGE_BITMAP, (LPARAM)hb);
    	//				DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
    			break;
    		case IDM_EXIT:
    			DestroyWindow(hWnd);
    			break;
    		default:
    			return DefWindowProc(hWnd, message, wParam, lParam);
    		}
    		break;
    	case WM_PAINT:
    		hdc = BeginPaint(hWnd, &ps);
    		// TODO: Add any drawing code here...
    //		LoadAndBlitBitmap(__T("XoaxLogo.bmp"), hdc);
    		EndPaint(hWnd, &ps);
    		break;
    	case WM_DESTROY:
    		PostQuitMessage(0);
    		break;
    	default:
    		return DefWindowProc(hWnd, message, wParam, lParam);
    	}
    	return 0;
    }
    
    // Message handler for about box.
    INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
    {
    	UNREFERENCED_PARAMETER(lParam);
    	switch (message)
    	{
    	case WM_INITDIALOG:
    		return (INT_PTR)TRUE;
    
    	case WM_COMMAND:
    		if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
    		{
    			 
    			EndDialog(hDlg, LOWORD(wParam));
    			return (INT_PTR)TRUE;
    		}
    		break;
    	}
    	return (INT_PTR)FALSE;
    }
Page 1 of 2 12 Last
  • Jump to page:

IMN logo majestic logo threadwatch logo seochat tools logo