Exemple #1
0
void Image::PrintInfo() const {

    float avg[4] = {0, 0, 0, 0};

    auto f = PixelAt(0, 0);
    float max[4] = {f.r, f.g, f.b, f.a};
    float min[4] = {f.r, f.g, f.b, f.a};

    for (int y = 0; y < m_Size.y; y++) {
        for (int x = 0; x < m_Size.x; x++) {

            auto col = PixelAt(x, y);

            float r = col.r;
            float g = col.g;
            float b = col.b;
            float a = col.a;

            avg[0] += r;
            avg[1] += g;
            avg[2] += b;
            avg[3] += a;

            max[0] = std::max(max[0], r);
            max[1] = std::max(max[1], g);
            max[2] = std::max(max[2], b);
            max[3] = std::max(max[3], a);

            min[0] = std::min(min[0], r);
            min[1] = std::min(min[1], g);
            min[2] = std::min(min[2], b);
            min[3] = std::min(min[3], a);
        }
    }

    assert( static_cast<unsigned>(m_Size.x * m_Size.y ) == m_Data.size());

    const size_t total = m_Size.x * m_Size.y;

    parallel_printf(" Image %dx%d, \n avg {%f,%f,%f,%f} \n min {%f,%f,%f,%f} "
                    "\n  max {%f,%f,%f,%f} \n",
                    m_Size.x, m_Size.y, avg[0] / total, avg[1] / total,
                    avg[2] / total, avg[3] / total, min[0], min[1], min[2],
                    min[3], max[0], max[1], max[2], max[3], max[0]);
}
Exemple #2
0
void Image::SaveToPNG(const std::string &filename) {

    FILE *fp = std::fopen(filename.c_str(), "wb");
    if (!fp)
        abort();

    png_structp png =
        png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
    if (!png)
        abort();

    png_infop info = png_create_info_struct(png);
    if (!info)
        abort();

    if (setjmp(png_jmpbuf(png)))
        abort();

    png_init_io(png, fp);

    // Output is 8bit depth, RGBA format.
    png_set_IHDR(png, info, m_Size.x, m_Size.y, 8, PNG_COLOR_TYPE_RGBA,
                 PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT,
                 PNG_FILTER_TYPE_DEFAULT);
    png_write_info(png, info);

    // To remove the alpha channel for PNG_COLOR_TYPE_RGB format,
    // Use png_set_filler().
    // png_set_filler(png, 0, PNG_FILLER_AFTER);

    std::vector<png_byte> row;
    row.resize(4 * m_Size.x * sizeof(png_byte));

    // Write image data
    for (int y = 0; y < m_Size.y; y++) {
        for (int x = 0; x < m_Size.x; x++) {

            auto col = PixelAt(x, y);

            float r = col.r * 255;
            float g = col.g * 255;
            float b = col.b * 255;
            float a = col.a * 255;

            if (r > 255) r = 255;
            if (g > 255) g = 255;
            if (b > 255) b = 255;
            if (a > 255) a = 255;

            row[x * 4] = static_cast<char>(r);
            row[x * 4 + 1] = static_cast<char>(g);
            row[x * 4 + 2] = static_cast<char>(b);
            row[x * 4 + 3] = static_cast<char>(a);
        }
        png_write_row(png, row.data());
    }

    // End write
    png_write_end(png, NULL);

    fclose(fp);
}
Exemple #3
0
ALERROR rgnCreateFromBitmap (HBITMAP hBitmap, HRGN *rethRgn)

//	rgnCreateFromBitmap
//
//	Creates a region from a bitmap

	{
	ALERROR error;
	HDC hDC = NULL;
	DWORD *pLine = NULL;
	RGNDATAHEADER rdh;
	BITMAP bm;
	int x, y;
	int iLineSize;
	char bitmapinfo[sizeof(BITMAPINFOHEADER) + 2 * sizeof(DWORD)];
	BITMAPINFOHEADER *pbmi = (BITMAPINFOHEADER *)bitmapinfo;

	//	Figure out the size of the bitmap

	GetObject(hBitmap, sizeof(bm), &bm);

	//	Prepare an output stream

	CMemoryWriteStream Output(bm.bmWidth * bm.bmHeight * sizeof(RECT));
	if (error = Output.Create())
		goto Fail;

	rdh.dwSize = sizeof(rdh);
	rdh.iType = RDH_RECTANGLES;
	rdh.nCount = 0;
	rdh.nRgnSize = 0;

	//	We assume that the bitmap already represents the bounding rect

	rdh.rcBound.top = 0;
	rdh.rcBound.left = 0;
	rdh.rcBound.bottom = bm.bmHeight;
	rdh.rcBound.right = bm.bmWidth;

	//	Write out the unitialized header; we will fill it in later

	if (error = Output.Write((char *)&rdh, sizeof(rdh), NULL))
		goto Fail;

	//	Prepare

	hDC = CreateCompatibleDC(NULL);
	iLineSize = AlignUp(bm.bmWidth, 32) / 32;
	pLine = (DWORD *)MemAlloc(iLineSize * sizeof(DWORD));

	ZeroMemory(pbmi, sizeof(BITMAPINFOHEADER));
	pbmi->biSize = sizeof(BITMAPINFOHEADER);
	pbmi->biWidth = bm.bmWidth;
	pbmi->biHeight = bm.bmHeight;
	pbmi->biPlanes = 1;
	pbmi->biBitCount = 1;
	pbmi->biCompression = BI_RGB;

	//	Loop over each scan line

	for (y = 0; y < bm.bmHeight; y++)
		{
		int xRunStart;

		GetDIBits(hDC,
				hBitmap,
				y,
				1,
				pLine,
				(BITMAPINFO *)pbmi,
				DIB_RGB_COLORS);

		//	Look for the beginning of a run

		x = 0;
		xRunStart = -1;
		while (x < bm.bmWidth)
			{
			if (xRunStart == -1)
				{
				//	If we're not in a run and we suddenly find a white pixel
				//	then we know that we begin a run

				if (PixelAt(pLine, x))
					xRunStart = x;
				}
			else
				{
				//	If we're in a run and we suddenly find a black pixel
				//	then we know that we're done

				if (!PixelAt(pLine, x))
					{
					RECT rcRect;

					rcRect.left = xRunStart;
					rcRect.top = y;
					rcRect.right = x;
					rcRect.bottom = y + 1;

					//	Add the rect to the region

					if (error = Output.Write((char *)&rcRect, sizeof(rcRect), NULL))
						goto Fail;

					rdh.nCount++;
					rdh.nRgnSize += sizeof(RECT);

					xRunStart = -1;
					}
				}

			x++;
			}

		//	If we were in a run, then end it

		if (xRunStart != -1)
			{
			RECT rcRect;

			rcRect.left = xRunStart;
			rcRect.top = y;
			rcRect.right = x;
			rcRect.bottom = y + 1;

			//	Add the rect to the region

			if (error = Output.Write((char *)&rcRect, sizeof(rcRect), NULL))
				goto Fail;

			rdh.nCount++;
			rdh.nRgnSize += sizeof(RECT);
			}
		}

	//	Close it out

	MemFree(pLine);
	pLine = NULL;

	DeleteDC(hDC);
	hDC = NULL;

	if (error = Output.Close())
		goto Fail;

	//	Update the header

	*(RGNDATAHEADER *)Output.GetPointer() = rdh;

	//	Create the region

	*rethRgn = ExtCreateRegion(NULL,
			Output.GetLength(),
			(RGNDATA *)Output.GetPointer());

	//	Done

	return NOERROR;

Fail:

	if (pLine)
		MemFree(pLine);

	if (hDC)
		DeleteDC(hDC);

	return error;
	}