• Advertisement

Dave Haylett

Member
  • Content count

    31
  • Joined

  • Last visited

Community Reputation

130 Neutral

About Dave Haylett

  • Rank
    Member

Personal Information

  • Interests
    Programming
  1. C# 10,000 PNG files!

    Hi Frob and Shaarigan. Thank you both for your guidance, and I certainly learned something new with regards GPU-friendly texture formats. In my application there is only a requirement to load up to 10 or so of these images at a time (they are blitted to a work area upon loading, and from there they make their way to the UI), and although the faster the better, a split-second delay is acceptable. After pondering over the superb advice I've been given for my query from everyone on here I think the best way for me to go is to stay with the PNGs (they are very small in size), but write a custom PAK file to load them all in one go during design time. This will total ~80mb. Some mundane processing needs to be carried out by myself whenever I add new images to the project, such as using TexturePacker to compress thumbnail versions of the new images, add some records to a SQLite db, etc. etc. and during this process I can a) stick the PNGs together into a PAK, and b) create a database table which tells my project at which byte each image is. At runtime this database is queried as part of user interaction, and so there'd be almost zero overhead to also pull back the start/length data for a given PNG when this happens. I should then be able to add this PAK to my VS project as a Resource, and write a function which can pull the data through into a WriteableBitmap; I use these commonly in my project. Then I'm back on track. Fingers crossed, and many thanks everyone, I value your input.
  2. C# 10,000 PNG files!

    Hi Brain (not Brian, sorry ), That's a good point. I will experiment with PhysFS tomorrow. As you can imagine the PNGs only compress down by about 4%, so I'm not gaining anything size-wise, but perhaps this option means that I can hold them all in memory in the archive without WPF uncompressing them all at runtime first (I assume this is what happens) and stealing hundreds of megs of RAM. I'll let you know how I get on. In the meantime I wonder if you have any thoughts about the other part of my problem: I also have 3000 ZIP files, totalling 500mb, which need to be dealt with in a similar way. They don't need to be held in RAM, but I need to distribute them with the project.
  3. C# 10,000 PNG files!

    Hey gec thanks for replying. Sorry yes this is a Windows program written in C#/WPF. It's a graphical front-end with lots of image blitting. The most common images are loaded in as Resources, but the 10,000 need to be accessed selectively as and when required, and quickly. The user can do this by flicking through a scrolling list of images. I did experiment with the sprite sheet option, using TexturePacker, however the image it produced was over 10,000 pixels square, and gave me an out-of-memory error when I tried to compile for Windows 32-bit (I don't necessarily want my app to be Win64 only). I do still use this option, but for quarter-size thumbnails of the images - they're all stuck together in a giant quilt, which I can blit from easily and quickly. It's just the standard size images that I need to manage. I do intend to use an installer, I'm just not sure how to manage the files easily as part of the project, and for them to be updated when I build new ones. Hi Brian, Thanks for the reply. That sounds interesting, however I don't think it'll be fast enough, as these images need to be selectable and blittable pretty quickly. Loading them individually from HDD does seem to work fast enough, but I don't think them being archived would be
  4. Hi all. My project is coming along wonderfully, and am starting to consider alpha deployment, and would like your advice. My project need access to 10,000 small PNG image files at runtime, each is only a few kilobytes each, which during development I used to load in directly from a fixed path on my HDD whenever one was needed (obviously not a solution for go-live), using something like this: img = new WriteableBitmap(new BitmapImage(new Uri(@screenshotsPath + filename))); The image would then be blitted onto a buffer screen, etc. etc. At a time, a few dozen would be being used. Now I'm thinking about deployment, and also when I produce an update to my app, there could be more images to add to the folders. So I'm considering the best way of a) deploying the images to the user as part of the project, and b) how to most easily handle updates to the app, whereby more images will be added. I have just experimented with adding them all as a Resource (!). This inflated the exe from 10mb to 100mb (not a major problem), increased the compile time from 3 secs to 30 secs (annoying), increased RAM usage from 500mb to 1.5gb (not a major problem either), but means that it solves my fixed directory issue, distribution issue, and update issue, simply by having the files all stuck into the executable. Here's the new code I'm using: img = BitmapFactory.FromResource("Shots/" + filename); The next thing I was going to try was to mark them as Content > Copy if Newer. This would resolve the executable size and RAM usage (and also the directory issue as well), however it seems that I'd need to highlight them all, and move them from Resource to Content. As an up-front job this isn't too bad, but as I add new images to the project, I'll need to go in and do this every time, which gets annoying, as the VS2015 default is Resource. Also, I'm not sure how this would work in terms of updates. Would something like ClickOnce deployment recognise new PNGs and install them to the users? I also have 3,000 ZIP files (~500kb each) which also need deploying and updating in the same way. These are currently read directly from my HDD until I can find a permanent solution for adding these to the project as well. Can anyone thing of a better way of doing what I'm trying to achieve? Thanks for any help folks.
  5. Hi Wessam. Thanks for your post. It has helped me get to the bottom of what the problem was! Even pasting in your above code didn't help! After stepping through some bits of my code on startup, I could see what was happening: In my Init phase what I do is create a new Image (with no fixed dimensions), and a new MainWindow, then say the Window's Content is the Image. The rest of my program blits graphics to the Image. The Image dimensions were being set from the Window dimensions once the Window was shown, so they match. For some reason, setting MainWindow.Content = Image messed up the dimensions of them both. I found that explicitly setting the Image dimensions to 1200x900 has fixed everything, as the Window's client area is now 1200x900. This was the original code (cut down a little): i = new Image(); w = new MainWindow(); w.Content = i; w.Show(); But adding this in after the first line fixes it. I don't even need a Grid or any other placeholder controls in the Window now: i.Width = 1200; i.Height = 900;
  6. I did try that in my frustration, but nope, it was always shorter and narrower. I'd like my client window to be 1200x900, but even taking the window title bar into account, it still doesn't explain why the window loses 15 pixels' width, given the window borders are only 2 or 3 pixels either side. Annoying and weird.
  7. Hi Tape_Worm, just wanted to follow up on this and say I've successfully migrated to SQLite in my project, so no more worries. The ATTACH functionality helped me join the two separate databases together which is a really nice function. Thanks again for your help.
  8. Thanks for the replies, no good though I'm afraid. I do have control over the width and height, it's just that the window ends up 15 pixels narrower and 39 pixels shorter than I want. If I set the size to 800x600, it ends up being 785x561! All I'm adding to the Window once it's been created is an Image (which is 1200x900) to fit the window, onto which I'm blitting loads of graphics. It all works fine, except I'm being short-changed on the window size!
  9. I have a simple MainWindow.xaml definition (most of it is default): <Window x:Name="MyProj" x:Class="MyProj.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:local="clr-namespace:MyProj" mc:Ignorable="d" Title="MyProj" Width="1200" Height="900" ResizeMode="CanMinimize" WindowStartupLocation="CenterScreen" /> Then I create the window in a code-behind with: w = new MainWindow(); w.Show(); But when the Window appears upon app start it is slightly smaller than 1200x900. In fact to get a 1200x900 window I need to specify 1215x939 in the MainWindow.xaml. At first I though I had to take the title bar and possible vertical scrollbar into consideration (!) but I don't have a scrollbar. What's going on??
  10. Hi Shaarigan. Thanks for your reply but I've decided to work around my issue by silently rebuilding the image in the background. The user only initially sees part of the image so I can kind of get away with it.
  11. Thanks mate this is all really useful. I'll look into it all. Appreciate your help.
  12. Hey Tape. You've pretty much got it - sorry it was probably not the best explanation. Database A is just full of records which I maintain, which the user queries via the app, and is distributed with the app. So you're saying I can essentially convert A from an .mdb file to some SQLite file and distribute that instead? (sorry I've never used SQLite before). Does SQLite have a front-end like Access, as I actually key in the records myself (don't worry it's much more fun than it sounds!) B will be created on the user's machine if it doesn't already exist there, somewhere in their My Documents or the like, and will hold their prefs. This is currently an .mdb as well, but I'm guessing I can make that a .SQLite too? If both A and B are SQLite files, then my app should be able to query them to its heart's content? Thanks for the NuGet link.
  13. Hi Tape_Worm, thanks for your responses. I'm tempted to get away from Access, but my question would be how do I get the data content which I as the developer provide from an .mdb file into the SQLite client on other users' machines? What I mean is, when a user starts up my app on their machine, and SQLite starts up with it, how does my app populate the tables in the client with data which I'm currently holding on my machine in Access? How do I distribute the data with the app?
  14. I'm using WriteableBitmaps in my project, and the tiffbitmapencoder and tiffbitmapdecoder classes to save off and restore a certain large graphic file from a WriteableBitmap to hard disc (the image is too big for the PNGbitmapencoder/decoder). This is working ok, but I'd like to encode to and decode from memory if possible, instead of having to save to disc. This is because, as part of the user experience this massive image can get wiped/cut down, and it takes a few precious seconds to reconstruct it again from scratch (which is also part of the user experience), but I can't afford the memory to just clone the whole image into another bitmap and clone it back again when needed, instead of rebuilding. Compressing it to TIF and holding in memory until it's needed again seems a viable option, but currently I can only compress/decompress to/from a file on disc. I've tried using MemoryStream instead of FileStream, and even though the encoder seems to like it, the decoder doesn't. Is it possible for me to achieve this?
  15. Hi everyone. I need some help with my project. It's a 2D-graphics-heavy WPF front-end app written in C#, which talks to two Access 2000 databases (yes I know, it's all I've got). It will be distributed freely on the internet, and so will be being used by Windows users of various installations/versions of Windows, Office, etc. One of the two databases (let's call it A), is intended to be read-only, and will be distributed with the app. It has half a dozen relational tables which I as the developer have populated, and is connected to in the app via OleDB Jet 4 with SQL querying the data now and then as the user uses the front-end. The database will be replaced whenever I release an update to the app. Database B is read/write, and contains end-user preferences, for example when they favourite something in my front-end, a Favourites table in here gets appended to. This database is not distributed with my app, and should not be overwritten, as it will lose user prefs, etc. and annoy my users. Whenever my app is run by a user, during initialisation database A will suck in the user data from database B (using simple SQL SELECT * INTO...), so that all the tables can be joined together by the SQL in database A (to include user prefs/favourites in SQL queries), and whenever the user favourites something, a record is created both in A (for the short-term session) and B (permanently). Database B isn't just about holding favourites, there is other user data in here as well, so there are 3 or 4 tables in B. So far, this is all working fine and I'm happy... Unfortunately my app is currently 32-bit, and it now needs to break the 32-bit memory barrier what with the size and volume of the graphics I'm pulling in (using the HDD is not really an option, as different graphics are needed kind of instantly and the hard disc would be being hosed and the app dog-slow otherwise, I suspect even off an SSD). I'm using VS2015, and switching to 64-bit will probably fix the memory problem, but it breaks Jet 4.0. I'm sure this is old news to most of you. To try to keep with 32-bit (and Jet4) but get the memory I need I've tried the -largeaddressaware toggle, and I've tried the editbin suggestion, but I just can't get these solutions to work in VS2015 no matter how hard I try. Are these definitely 100% solutions to 2gb memory limit in 32-bit applications? Should they always work? Am I dumb in being unable to get this to work? So otherwise I'm resigned to migrating to 64-bit, and having to get around the database issue, not the memory issue. My users will be using a variety of Windows versions (probably 7 and 10), and I'm sure various versions of Office, and so my solution for querying my two Access databases needs to be pretty open if possible. Googling has suggested I switch from JET4 to ACE12, but this is apparently requiring me to uninstall Office 2000 and install a 64-bit version (which I don't have), so I can't use it, and I suspect any users who also have an old version of Office installed won't be able to use it either? Googling has also suggested I use MS SQL Server. This sounds fine if there's such a thing as a "lite" local version which can manage database access, but I still need to somehow get the data from the databases (A.mdb and B.mdb) into the SQL Server each time the users fire up my app. The only solution I can think of at the minute, is to export all the tables from database A into CSVs every time I update the data in there, and have the app import them in a lame way, and also convert database B into some crappy text file which gets written to whenever the user changes a preference. I'd much rather use SQL to do all this if possible, as when the user browses around the app, queries involving joining several tables in A are regularly created and executed to adjust the user's experience/return search results/etc. So to summarise my misery, is there either an easy reliable way for me to keep with 32-bit/Jet4 and be able to address >2gb. Or is there instead an easy reliable way for me to switch to 64-bit and successfully query two Access databases without requiring all my users to have 64-bit Office installed? Thanks for reading and I hope someone can help.
  • Advertisement