Path: csiph.com!v102.xanadu-bbs.net!xanadu-bbs.net!feeder.erje.net!eu.feeder.erje.net!eternal-september.org!feeder.eternal-september.org!news.eternal-september.org!.POSTED!not-for-mail From: Eric Sosman Newsgroups: comp.lang.java.programmer Subject: Re: is that possible to include a small PNG file as part of Java class? Date: Sun, 29 Jun 2014 08:15:50 -0400 Organization: A noiseless patient Spider Lines: 71 Message-ID: References: Mime-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Injection-Date: Sun, 29 Jun 2014 12:15:51 +0000 (UTC) Injection-Info: mx05.eternal-september.org; posting-host="bd4e1cba8d8592bec5d5ed9e4537fbfd"; logging-data="7814"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX19Kyxp94cw0r1FwH/M7jKYz" User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:24.0) Gecko/20100101 Thunderbird/24.6.0 In-Reply-To: Cancel-Lock: sha1:nyU03AeR2rCvAWe6htgk2mjvGWI= Xref: csiph.com comp.lang.java.programmer:28868 On 6/29/2014 5:14 AM, Wanja Gayk wrote: > In article , Eric Sosman (esosman@comcast- > dot-net.invalid) says... >> >> On 6/23/2014 12:02 PM, www wrote: >>> Hi: >>> >>> I have a simple Java class: Abc.java. The method within it needs to access a small PNG file(it's an icon picture). Right now, this picture file("abc.png") is located at nonsrc/icons/abc.png >>> >>> So this class is a bit pain. Abc.class won't work in the absence of abc.png. When I create an executable JAR, this is pain: always need to remember to include abc.png file inside it. >>> >>> I am wondering if there is a way that I can "convert" abc.png into some sort of Java code and I can put it in Abc.java. So Abc.class alone can perform the job, without the need of presence of abc.png. Is that possible? >>> >>> Hope I have explained my intention well. >> >> Martin Gregorie's response seems to be good advice. However, if >> you simply *must* incorporate your PNG image as a class, you could do >> so with a big byte[] array: >> >> private static final byte[] PNG_BUFFER = { >> (byte)0x89, 0x50, 0x4E, 0x47, ... }; >> >> public static Image getMyPNG() { >> return ImageIO.read(new ByteArrayInputStream(PNG_BUFFER)); >> } >> >> However, this approach will only work for fairly small images. The >> problem is that Java class files have no way to store an initialized >> array: The byte[] array above actually compiles to the equivalent of >> >> private static final byte[] PNG_BUFFER = new byte[whatever]; >> static { >> PNG_BUFFER[0] = (byte)0x89; >> PNG_BUFFER[1] = 0x50; >> PNG_BUFFER[2] = 0x4E; >> PNG_BUFFER[3] = 0x47; >> ... >> } >> >> ... with about four or so bytecode instructions per array element. > > Just wondering: why not use a string? > > private static final String imageAsBase64 > = "SOME_BASE64_STRING_GOES_HERE"; > > public static Image getMyPNG() { > return ImageIO.read( > new ByteArrayInputStream( > SomeUtil.base64ToBytes(imageAsBase64))); > } > > Of course Base64 is notoriously inefficient (there's still Base85 > though), but he's talking about "small PNG files", not large ones. >[...] I'd thought about using something like private static final String PNG_BUFFER = "\u8950\u4E47..."; ... which could then be unpacked at run time into a byte[] of twice as many elements and used as before. But that seemed so foully ugly that I had to suppress the urge to vomit, so I didn't mention it. Base64 simply didn't occur to me, and when I saw it mentioned by others I said "Duh!" and delivered a self-administered dope slap. -- Eric Sosman esosman@comcast-dot-net.invalid