Image rd file compress

Pages: 1234
I need to downsize 200x200 tga to 100x100. So I want to take every 2nd pixel along each row and column. Is it a good approach?

Did you try it?
I am still not clear how that can be done, doing some research on it. any samples would really help here. how to make copy of original image file which is 200x200 and then downsize it to 100x100?
Last edited on
Below is what I tried so far, but this just experimental. I am not sure if its correct way to do.
My understanding is that to downsize 200x200 to 100x100, need to sample several pixels from the original image, take average of it, and then use it as your new image. Any idea how this can be done?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#include<iostream>
#include<fstream.h>
#include<conio.h>
#include<string.h>
#include<math.h>
using namespace std;
struct pix {
unsigned char b,g,r; } pixel;
int L=255;//L is set to highest intensity per byte
char Header[54];
ifstream in;
ofstream out,out1;
int main() {
char infile[]=”d:\\test.bmp”;
char outfile[]=”d:\\test-mod.bmp”;
char imdata[]=”d:\\testdata.dat”;
in.open(infile,ios::in|ios::binary);
in.read((char*)(&Header),sizeof(Header));
out.open(outfile,ios::out|ios::binary);
out.write((char*)(&Header),sizeof(Header));
out1.open(imdata,ios::out);
while(!in.eof()) {
in.read((char*) (&pixel),sizeof(pixel));
out1<<“Original Image : “<<(int)pixel.r<<” , “<<(int)pixel.g<<” , “<<(int)pixel.b<<endl;
pixel.r=pixel.r/3;
pixel.g=pixel.g/3;
pixel.b=pixel.b/3;
out.write((char*) (&pixel),sizeof(pixel));
out1<<“Modified Image : “<<(int)pixel.r<<” “<<(int)pixel.g<<” “<<(int)pixel.b<<endl;}
in.close();
out.close();
out1.close();
getch(); }
Last edited on
loop....
go across row 1 and row 2 in the original image.
for each byte (don't give a rats rearend what color it means)
new row1 (each byte here) = (byte1+byte2)/2
then you do it again for rows 3 and 4 of the original making row 2 of the new one.

you can do this same with 3 rows. that means every 6 original rows needs to be 3 new rows to cut it in half. so 1,2,3 make a row, 2,3,4 OR 3,4,5 make a middle row, and 4,5,6 make the third row. and so on.
how to create copy of original image and downsize it to another new image?
can i copy this way for the actual image file? then apply the above logic to get the modified image which is down size to half the size of actual image? or should i use std::copy?


1
2
3

char *file_name = "test.bmp";
char *file_namecopy = "test_copy.bmp";
Last edited on
its unclear what you do not understand.

open an image file.
break out of the image file a usable image portion, usually this is a container of bytes in either {GREY}, {RGB}, {RGBA} format or whatever format the image type uses (there are other ways to represent color, but RGB won the fight and most use that). Most use RGB for color and one byte for greyscale, but they may also compress the stream so you have to decompress it into this format.

then do the above logic.

then make a new image with the correct information (the dimensions changed, nothing else, so you can copy the original and change the dimension fields) in the headers and the new image data parts (remember to recompress it if the format needs it).
then write the new file and test it by opening it in an image editor and verifying how it looks and that the dimensions are changed and so on.

if you can find an image editor that can process a file that is just a RGB binary file without headers, you can skip all the format specific stuff and work on your core code. The image format stuff should be 'apart' from the 'work' so if you use a new format, the code can adopt it easily.
Last edited on
The new image that is created will have the downsized image. To make a copy of original image should I use std::copy? Also how to read the color value of 24bit image format at all the pixel.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <fstream>
#include <string>

struct ds {
   std::string name;
   std::string descrp;
   int number;

   void save(const std::string& filename) {
      std::ofstream file(filename.c_str());
      file << name.c_str() << std::endl
           << descrp.c_str() << std::endl
           << num;
   }
   void load(const std::string& filename) {
      std::ifstream file(filename.c_str());

      getline(file, name);
      getline(file, descrp);
      file >> num;
   }
};

Last edited on
you probably can get std::copy to work. Depending on what you have, that may or may not be necessary.
I mean, if your image file is just a vector<unsigned char> mytgafile(filesize); then vector<unsigned char> outfile; outfile = mytgafile will do the job. Then you just adjust the bytes you need to update and resize, then write it out.

I don't know how to read it (meaning the TGA raw byte format, I have not looked at it). Assuming you read the whole file at once into a vector as above, you probably mean iterate, not read? for(where the rgb data starts, until end of file, ++) .... but here again, is your file compressed or not? If it is compressed, you need to decompress into a byte container, if it is not, you can work directly with the bytes you read in via file.read().
You don't need to get fancy with this stuff. Pull the bytes off the disk, jump to the locations you need in the header, unravel the RGB location and format, crank it out.

Last edited on
I need to create a copy of actual image to downsize to half the real size of actual TGA( must be uncompressed), and must support for both RGB, RGBA.
ok. so do it ;)
if you don't need to deal with compression, just read the file in one go with read() and jump to the RGB or RGBA data, do your averages, ... its exactly what I said, taking the 'don't need to deal with compression' path.
To make copy of actual file, i tried this way. But not able to create copy.is something wrong here? I am trying to read bmp file and extract data, then create new bmp file manually with the same header and data as that of the original. instead of manual should i use ifstream::read??

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#include <iostream>
#include <fstream>
using namespace std;
 
int main()
{
    string line;
    
    //Creating ofstream & ifstream class object
    ifstream ini_file {"original.bmp"};
    ofstream out_file {"originalcopy.bmp"};
 
    if(ini_file && out_file){
 
        while(getline(ini_file,line)){
            out_file << line << "\n";
        }
 
        cout << "Copy Finished \n";
 
    } else {
        //Something went wrong
        printf("Cannot read File");
    }
 
    //Closing file
    ini_file.close();
    out_file.close();
 
    return 0;
}
Last edited on
Open the files in binary mode.

1
2
3
4
5
6
7
8
if( std::ifstream in{ "original.bmp", std::ios::binary } )
{
    if( std::ofstream out{ "originalcopy.bmp", std::ios::binary } )
    {
        out << in.rdbuf() ;
        std::cout << "file was copied\n" ;
    }
}
adding to the above^^ getline is for text files. binary files do not have lines that make sense. if they have end of line markers, it is just an accident of the bytes in the file.

You seem to be in over your head.
I would back up, and do these simple things first (you do not have to, but this will simplify away the gory details and leave you just a simple but critical part to master):
1) locate and download an image viewer that can look at RGB files. That is, just a byte dump of the raw image data, where you tell the viewer the height and width, or its the only thing in the header of the file, something very simple.
2) write a small one of these, do something like for 200x200 write 0,0,i++ for example to have an image that is a gradient from white to black of shades of blue, repeating here and there. Do this by learning to write the binary file. View it in your tool from #1
3) now try to cut that in half with your averages and write a new file from the original that is half sized. verify its sizes in your OS file details
4) slowly work back to your TGA program using what you have learned.
I am able to manually create a copy of original file now using binary mode. now need to see if the above logic works or not. then need to verify the image whether it got downsize to half the original size.
Can't you use a library to read/write TGA files.
For instance, this one: https://github.com/aseprite/tga (MIT license, non-viral)
I cant use any 3rd party libraries, need to read/write TGA without that.
It would still be a good idea to study the code in a library and get an understanding of what you need to do.

And here is some code for resizing pixels in an image (Public Domain):
https://github.com/nothings/stb/blob/master/stb_image_resize.h
Ok, I will go through it.
Last edited on
Yes; but why do you want to use the C subset of the standard library?
Pages: 1234