Yeah thanks for that Henke... Guess I'll have to try and figure it out on my own. What program do I need to mess with ASM code?
Technically, he isn't wrong.
There are two ways to solve this problem:
1: As Henke said, you use a debugger emulator to show the program that decompresses the graphics as the game is running.
Obviously you'll need to understand that program, that means you'll need to know that ASM language. NES assembly is simple so you're lucky (I'd give you a tutorial I made but it's in another language)
So, now you have the decompression
program that makes the conversioncompressed_ROM_graphics>>uncompressed_VRAM/PPU_graphics
You make two programs in C++/Java/whatever you like, one that does the decompression above, and another that re-compresses and recreate the compressed data in the ROM (that you'll need to study)
You do some tests to make sure it's fine, with the exact same data unchanged and see if the recompression is successful.
You can often end up with files bigger than the original (if smaller, you could fill with 00/FF/garbage data)
In that case, you'll need to move the data elsewhere with enough space... overflowing and overwriting other files is the best way to failure
Ironically this method does not require changing the programming of the game.
2: A more sane way is to expand the ROM (not the easiest thing to do on NES)
Put the uncompressed graphics (ripped from the PPU/VRAM, or you could do a part of solution 1 and do a decompressor only) in the new space
Change the programming of the game (ASM):
the instruction: "do_decompression_program" becomes "do_program_that simply_takes_uncompressed_data_as_is_from_ROM_to_RAM"
(of course you won't find nice looking neon glowing labels like that in the programming)