Posted: Sat Apr 23, 2011 5:23 pm Post subject: Re: RE:Insectoid\'s Summer Programming Challenge
ultimatebuster @ Sat Apr 23, 2011 1:17 pm wrote:
I'm not sure if Python can write non-text format via file.write
nm it can. though i think i has to be direct HEX code or via struct.
Following writes a text file in binary directly.
code:
with open("test.dat", "wb") as f: f.write('\x75\x6C\x74\x69\x6D\x61\x74\x65\x62\x75\x73\x74\x65\x72')
You can also use ord() to convert a single character to it's ordinal code (the character's numeric value) and chr() to go back.
Sponsor Sponsor
RandomLetters
Posted: Sat Apr 23, 2011 7:30 pm Post subject: Re: Insectoid's Summer Programming Challenge
Well, finished the program to load a 24 bit bitmap, and apply a tunnel effect, like that terrible, terrible feature in ipad photobooth
It's still extremely slow to something like MS paint however, which most of the time is taken because of loading the bitmap into an array.
code:
public void loadBmpPixelArray() throws IOException {
FileInputStream in = new FileInputStream(file);
bmpPixelArray = new byte[Math.abs(bmpInfoHeader.height)]
[Math.abs(bmpInfoHeader.width)]
[3];
for(int i = 0; i < bmpHeader.offset; i++) { //reads in bytes from offset of bitmap
in.read();
}
byte[] buffer = new byte[(bmpInfoHeader.width % 4)]; //buffer at the end of each row to keep multiple of 4
if(bmpInfoHeader.height >= 0) { //check sign of "height" info, if it's positive, the image is "upside down"
for(int r = bmpPixelArray.length - 1; r >= 0; r--) {
for(byte[] bmpPixel : bmpPixelArray[r]) {
in.read(bmpPixel); //reads 3 bytes into the pixel array
}
in.read(buffer);
}
} else {
for(int r = 0; r < bmpPixelArray.length; r++) { //not upside down
for(byte[] bmpPixel : bmpPixelArray[r]) {
in.read(bmpPixel);
}
in.read(buffer);
}
}
bmpOriginal = bmpPixelArray.clone();
}
Is there any way to optimize this? Currently, I have a 2D array of pixels, which are themselves an array of 3 bytes.
DemonWasp
Posted: Sun Apr 24, 2011 10:28 am Post subject: RE:Insectoid\'s Summer Programming Challenge
BufferedInputStream:
code:
InputStream in = new BufferedInputStream ( new FileInputStream ( file ) );
// Or, for extra fun:
DataInputStream in = new DataInputStream ( new BufferedInputStream ( new FileInputStream ( file ) ) );
// that last one allows you to read whole integers and so on easily
Also, don't forget to close your input streams when you're done with them.
DtY
Posted: Sun Apr 24, 2011 12:07 pm Post subject: Re: Insectoid's Summer Programming Challenge
RandomLetters @ Sat Apr 23, 2011 7:30 pm wrote:
Well, finished the program to load a 24 bit bitmap, and apply a tunnel effect, like that terrible, terrible feature in ipad photobooth
It's still extremely slow to something like MS paint however, which most of the time is taken because of loading the bitmap into an array.
code:
---snip
Is there any way to optimize this? Currently, I have a 2D array of pixels, which are themselves an array of 3 bytes.
There's a lot of overhead in using an array for each pixel. Instead, make each pixel a single integer, made up of red<<16+green<<8+blue. You'll have to use some weird bitmasking stuff to get the individual components, but it will be a lot more space efficient. It may seem odd at first that storing 24 bits in 32 bits is more space efficient, but to creating an array requires creating a pointer, which is itself 32 bits, and then 8 bits for each index in the array.
RandomLetters
Posted: Sat Apr 30, 2011 9:01 pm Post subject: RE:Insectoid\'s Summer Programming Challenge
Thank's for the advice. It's almost instantaneous now.
Here's the mostly complete product. Bit operations are surprisingly useful.
//makes the circle tunnel effect on pictures by changing pixels
public void applyTunnelEffect() {
int r = bmpPixelArray.length/3;
int xC = bmpPixelArray[0].length/2;
int yC = bmpPixelArray.length/2;
int dx, dy;
int x1, y1;
double angle;
int[][] bmpOriginal = new int[bmpPixelArray.length][bmpPixelArray[0].length];
for(int i = 0; i < bmpOriginal.length; i++) {
bmpOriginal[i] = bmpPixelArray[i].clone();
}
for(int y = 0; y < bmpPixelArray.length; y++) {
for(int x = 0; x < bmpPixelArray[y].length; x++) {
dx = x-xC;
dy = y-yC;
if(dx*dx + dy*dy > (r)*(r)) {
angle = Math.atan(dy/(double)dx);
if(dx < 0) {
angle += Math.PI;
}
x1 = (int) (xC + r*Math.cos(angle));
y1 = (int) (yC + r*Math.sin(angle));
bmpPixelArray[y][x] = bmpOriginal[y1][x1];
}
}
}
}
public void loadBmpPixelArray() throws IOException {
BufferedInputStream in = new BufferedInputStream(new FileInputStream(file));
bmpPixelArray = new int[Math.abs(bmpInfoHeader.height)]
[Math.abs(bmpInfoHeader.width)];
System.out.println(bmpPixelArray.length);
System.out.println(bmpPixelArray[0].length);
for(int i = 0; i < bmpHeader.offset; i++) {
in.read();
}
public void loadBmpHeader() throws Exception {
BufferedInputStream in = new BufferedInputStream(new FileInputStream(file));
BitmapHeader bmpHeader = new BitmapHeader();
BitmapInfoHeader bmpInfoHeader = new BitmapInfoHeader();
byte[] buffer2 = new byte[2];
byte[] buffer4 = new byte[4];
public static final int byteArrayToInt(byte[] b) {
return (b[3] << 24)
+ ((b[2] & 0xFF) << 16)
+ ((b[1] & 0xFF) << 8)
+ (b[0] & 0xFF);
}
public static final long unsignedIntToLong(byte[] b)
{
long l = 0;
l |= b[3] & 0xFF;
l <<= 8;
l |= b[2] & 0xFF;
l <<= 8;
l |= b[1] & 0xFF;
l <<= 8;
l |= b[0] & 0xFF;
return l;
}
public static final int unsignedShortToInt(byte[] b)
{
int i = 0;
i |= b[1] & 0xFF;
i <<= 8;
i |= b[0] & 0xFF;
return i;
}
}
class BitmapHeader {
public long filesize; //size of file (unreliable?)
public int reserved1; //unused
public int reserved2;
public long offset; //offset of start of pixel array
@Override public String toString() {
StringBuilder result = new StringBuilder();
String NL = System.getProperty("line.separator");
class BitmapInfoHeader {
public long headersize; //size of this header in the file (must 40)
public int width; //width of bitmap (in pixels)
public int height; //height of bitmap (in pixels)
public int nplanes; //number of color planes (must 1)
public int bitspp; //bits per pixel (color depth)
public long compresstype; //compression method (must 0 for this)
public long imgsize; //raw bitmap data size
public int hres; //horizontal res (pixels/meter)
public int vres; //vertical res (pixels/meter)
public long ncolors; //number of colors
public long nimpcolors; //number of important colors (unused)
@Override public String toString() {
StringBuilder result = new StringBuilder();
String NL = System.getProperty("line.separator");
Posted: Mon May 02, 2011 2:47 am Post subject: Re: RE:Insectoid\'s Summer Programming Challenge
DtY @ Sat Apr 23, 2011 5:23 pm wrote:
You can also use ord() to convert a single character to it's ordinal code (the character's numeric value) and chr() to go back.
In high school the first time I worked with a binary format I opened the file in text mode, translated the characters to their ordinal codes, made the requried modifications, translated the ordinal codes back to characters and outputted the file in text mode. Heh.
ultimatebuster
Posted: Mon May 02, 2011 9:40 am Post subject: Re: RE:Insectoid\'s Summer Programming Challenge
Brightguy @ Mon May 02, 2011 2:47 am wrote:
DtY @ Sat Apr 23, 2011 5:23 pm wrote:
You can also use ord() to convert a single character to it's ordinal code (the character's numeric value) and chr() to go back.
In high school the first time I worked with a binary format I opened the file in text mode, translated the characters to their ordinal codes, made the requried modifications, translated the ordinal codes back to characters and outputted the file in text mode. Heh.
Now that's how you do it. Rebel.
Velocity
Posted: Thu Jan 12, 2012 12:29 am Post subject: RE:Insectoid\'s Summer Programming Challenge
what is the difference between binary and trinary?
Sponsor Sponsor
Insectoid
Posted: Thu Jan 12, 2012 7:48 am Post subject: RE:Insectoid\'s Summer Programming Challenge
What's the difference between a bicycle and a tricycle?
mirhagk
Posted: Thu Jan 12, 2012 10:49 am Post subject: RE:Insectoid\'s Summer Programming Challenge