Link to home
Start Free TrialLog in
Avatar of maxb
maxb

asked on

Many JPG images in project

Hi All,
My project needs to use about 120 JPEG (!) images of varying sizes that need to be compiled into the project. I dont want users to be able to change these images (as complicated as possible for them to edit so no simple .RES file)

What is the best solution as well as how do I read the image (whatever format you suggest) into a TImage (or similar) component?

Thank you!
Avatar of -Karamja-
-Karamja-

>I dont want users to be able to change these images.

Dont think you can, The only thing I could think of is using a exe packer (UPX, ASPack)
Avatar of maxb

ASKER

I guess anything harder than just changing the .RES or images in a directory would suffice as "not easy to change images easily". Maybe compile into a DLL? I have no experience working with DLLs at all...
http://www.greatis.com/delphicb/tips/lib/resource-bmpfromdll.html

Above link shows an example. Related links at the bottom shows how to include JPEG in DLL.
Avatar of maxb

ASKER

The DLL idea is just something I threw out, is that really the best solution for my problem?
Avatar of maxb

ASKER

Ok, even if DLL is the best solution... That link doesnt provide a way to put the JPGs inside the DLL. It simply shows an example of how to have the DLL as a loader... Need more help
hello maxb , , I am not really clear about what it is that you are trying to do? ? I am wondering why you say that you want to prevent -
"I dont want users to be able to change these images"

why do you care about someone running a Resource Editor and changing your images to something they might prefer?, , , I will have to guess, since you mention change Image, that you do not want someone to Get the special images out of your executable?

I would stick to a RES resource, and just remove the first several standard bytes of the JPEG file header, and then add those back when I got the image data from the resource, ,

The only other way I have heard of to stick data into an executable, is to Tack it on to the End of the program file, but you will need a separate program to stick the data onto it, but the program can read the data whenever it is running
Avatar of maxb

ASKER

Exactly, I want to make it difficult for them to get the images out and replace them with something else. Isn't there a way to compile a res into a DLL (makes it more difficult to extract the images)?

I have no idea on how to remove the JPG header... although that sounds like a great option...

Also, how do I even get a JPG into a RES? It'll only take BMP and ICO
Gwena has a component that allows you to 'embed' your files to your EXE and retrieve/update it during runtime http://www.geocities.com/gacarpenter386
Avatar of maxb

ASKER

Thank you but I dont think that would work because I will have to compare the hash of the exe every time they connect to my server to ensure it has not been tampred with. Also, it would bring the EXE size to 5 or 6mb, isn't there some sort of memory problem with an EXE that size? I have to admit I don't know much about the topic.
well, I guess you could always encrypt the jpg before appending it to your EXE, that way, your users won't know what to temper anyway ;-)

by the way, if you add the JPGs into a DLL, isn't the DLL file size going to be 5-6MB too? Never had problems with .exe of 5-6MBs yet, heh. Photoshop's exe is more than 15MB, by the way :-)
http://cc.borland.com/ccweb.exe/listing?id=12708

I'll see if I can put together a code sample for you. Creating a resource is like: create a data.rc file, put data in it, link it into a dll project using {$R *.RC} or {$R *.RES}, compile it, done.

Then use the code I gave you to extract the data. You can do it with any file: JPG, HTML, AVI even EXE if you like.

code for the .rc file

1 JPEG "test1.jpg"
2 JPEG "test2.jpg"
3 JPEG "test3.jpg"
Avatar of maxb

ASKER

DragonSlayer,
So from what you're saying, I can just put a bunch of TImage components on a "resource" form inside my project. Select the JPG for each (at design time). Then just use Image.Picture as a source throughout the app? Is there a downside to doing this? What's a point in using resource DLLs (other than sharing between apps) if you can just compile the images into the exe?

Piraeas,
I would love to see what that code looks like. Thank you.
Well, the downside is, everytime you update/patch your software, you will have to redistribute the whole chunk of 5-6MB file.
Avatar of maxb

ASKER

Good point :) I don't know why I didn't think of that. So is the DLL approach the best?
well, it's either the DLL, or the Database, or you can come up with your own "storage format"...
Here is a storage component (with encryption and compression) that I've used in some projects quite a while ago... http://www.xarka.com/download/hkstrm17.zip (THKStream)

To quote from the Author's readme:

"HKStreams is a component that enables you to easily save and load many streams into one file. The streams can be stored with LHA compression if wanted, and can also be encrypted with blowfish. THKStreams is also smart, if you load afterwards an encrypted or compressed (or both) file, it will know how to read it, and can also call your event that asks the user for a password if needed.Can also handle wrong passwords or corrupt files.

This program works by saving the streams in a file with a 10 byte header that contains information whether encryption and/or compression exists, and also a series of bytes that are used for a test if the correct password was entered, in the case of encryption (of course only those 8 bytes are known).

With this you can implement with little code the ability for users to protect their files if they want it, and also compress their data. However you will have to warn them that if they forget the password, there will be no way to regain the data (well except maybe if they work in CIA)"



DragonSlayer.
And here's another of the file storage alternative, but this one's not free: http://www.aidaim.com/products/sfs/sfs_spec.php
Avatar of TheRealLoki
I think I'd just have the jpg's as files, but keep a crc checksum in the application. run a quick checksum when the app starts (equiv time to loading the app with the jpg's embedded anyway) but the files are then only loaded into memory when they are needed. Saves resources
You can use my ExeMod.pas unit to add the jpg files to the end of the exe.

You will not have any problems with the exe size... and the images are easily
scrambled to make them hard for users to alter.

The images are read from the exe file on disk at runtime..much the same as
working with simple jpg files on disk.... you call the images by name...it's easy.

ExeMod.pas gives you an easy way to keep everything in the exe instead
of in seperates files...and it replaces the utility of res files and gives you
the ability to change the stored data at runtime...something that is really
hard to do with a res file.

There are some demos on my site that will help you
or I can make a small custom demo if you need it.  :-)
PS: Gwena, I myself can't seem to access your geocities site anymore... did you move your site?
no..the site is still up..
I just checked to make sure :-)

http://www.geocities.com/gacarpenter386
strange... maybe my ISP is having problems with geocities? heh...
geocities has ads and/or popups. If you use a popup or ad blocker, it is likely the site will not work.
Avatar of maxb

ASKER

Still waiting for the DLL help... unless the streams are a better approach?

Just to finalize this up, can you guys just tell me how I create a RES file that contains JPGs, compile it into a DLL, view the image in my app?

Thank you!!
ASKER CERTIFIED SOLUTION
Avatar of Member_2_248744
Member_2_248744
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
If you can have a separate file with your images, , ,  just my opinion  , , , you might should consider using Gwena's ExeMod for a sparate file, seems like if you can do a "compare the hash of the exe" for a DLL, seems like you could on a ExeMod file.. . or do a program with a ExeMod jpg tack on, , , and  then do a hash compare on your  program with ExeMod? I would think the ExeMod would give you some more protection than a resource.

oh as far as "protection", you might use some meaning less resource types and names
instead of  "aJPEG", , use "BVOYD" or "KXRSY"

and instead of "backGround"  use  "najybfok" or "kijsr4d"
Avatar of maxb

ASKER

var
ResStm : TResourceStream;
hLibJpg: THandle;
Jpg1: TJPEGImage;
begin
Application.CreateForm(TMain, Main);
hLibJpg := LoadLibrary('max1.dll');
if hLibJpg = 0 then begin
  ShowMessage('ERROR - Could NOT load library');
  Exit;
end;

ResStm := TResourceStream.Create(hLibJpg, 'pic1', 'aCategory');
try
  Jpg1.LoadFromStream(ResStm);   <-- Access Violation
 // Main.drgpic.
  Main.Drg2.Canvas.Draw(199,14, Jpg1);
  ShowMessage('Loaded');
finally
  FreeLibrary(hLibJpg);
  FreeAndNil(ResStm);
  FreeAndNil(Jpg1);
end;


I keep getting an Access Violation error on the line above. Main.Drg2 is a TPaintBox
???

how can you access something that does not exist?
In your code you do NOT create a  Jpg1, so you can not access it . . . .


Jpg1 := TJPEGImage.Create;  // you need this line
ResStm := TResourceStream.Create(hLibJpg, 'backGround', 'aJPEG');
Avatar of maxb

ASKER

Ok, I don't get it.

No more access errors (dumb mistake).. but even though the DLL loads (looks like fine), there is no image visible on the canvas...

However, if I draw on the current form (login), the image shows. What I really need is the image to be visible on "main" and the action launched by "login". Please help
I can not understand what you are asking, and do not see what you are having a problem?
If you get a JPG image, that is all that loading a resource DLL and getting a resource (a JPG file in this case) form a DLL is suppose to do, onec you have the JPG , you can do anything you want to do with it, in my example, I was only doing a simple show the JPG, but you can make the

Jpg1: TJPEGImage;

a class or unit global variable, and not free it at the end of your DLL load procedurethen use it in the Main (whatever that may be), once you have the JPG, do whatever you want to with it. . . if you want to have it in your main then put the

Jpg1: TJPEGImage;

variable in your main and use it there
if you want a persistant image then put the jpg in a TImage