void Gosu::saveImageFile(const Gosu::Bitmap& bitmap, Gosu::Writer writer, const std::wstring& formatHint) { unsigned char* rgba = const_cast<unsigned char*>(reinterpret_cast<const unsigned char*>(bitmap.data())); // TODO: Use the new *_to_func functions in stb_imagewrite.h instead: // https://github.com/nothings/stb/blob/master/stb_image_write.h#L39 int length; unsigned char* png = stbi_write_png_to_mem(rgba, 0, bitmap.width(), bitmap.height(), 4, &length); if (png == 0) throw std::runtime_error("Could not save image data to memory"); try { writer.write(png, length); } catch (...) { STBIW_FREE(png); throw; } STBIW_FREE(png); }
void Gosu::saveImageFile(const Gosu::Bitmap& bitmap, Gosu::Writer writer, const std::wstring& formatHint) { unsigned char* rgba = const_cast<unsigned char*>(reinterpret_cast<const unsigned char*>(bitmap.data())); int length; unsigned char* png = stbi_write_png_to_mem(rgba, 0, bitmap.width(), bitmap.height(), 4, &length); if (png == 0) throw std::runtime_error("Could not save image data to memory"); try { writer.write(png, length); } catch (...) { STBIW_FREE(png); throw; } STBIW_FREE(png); }
void Gosu::saveImageFile(const Gosu::Bitmap& bitmap, Gosu::Writer writer, const std::wstring& formatHint) { int ok; if (isExtension(formatHint.c_str(), L"bmp")) { ok = stbi_write_bmp_to_func(stbiWriteToWriter, &writer, bitmap.width(), bitmap.height(), 4, bitmap.data()); } else if (isExtension(formatHint.c_str(), L"tga")) { stbi_write_tga_with_rle = 0; ok = stbi_write_tga_to_func(stbiWriteToWriter, &writer, bitmap.width(), bitmap.height(), 4, bitmap.data()); } else { ok = stbi_write_png_to_func(stbiWriteToWriter, &writer, bitmap.width(), bitmap.height(), 4, bitmap.data(), 0); } if (ok == 0) throw std::runtime_error("Could not save image data to memory (format hint = '" + Gosu::wstringToUTF8(formatHint) + "'"); }
// Very easy special case. Gosu::Bitmap Gosu::createText(const wstring& text, const wstring& fontName, unsigned fontHeight, unsigned fontFlags) { FormattedString fs(text.c_str(), fontFlags); if (fs.length() == 0) return Bitmap(1, fontHeight); vector<FormattedString> lines = fs.splitLines(); Bitmap bmp(1, lines.size() * fontHeight); for (int i = 0; i < lines.size(); ++i) { if (lines[i].length() == 0) continue; unsigned x = 0; vector<FormattedString> parts = lines[i].splitParts(); for (int p = 0; p < parts.size(); ++p) { const FormattedString& part = parts[p]; if (part.length() == 1 && part.entityAt(0)) { Gosu::Bitmap entity = entityBitmap(part.entityAt(0)); multiplyBitmapAlpha(entity, part.colorAt(0).alpha()); bmp.resize(max(bmp.width(), x + entity.width()), bmp.height()); bmp.insert(entity, x, i * fontHeight); x += entity.width(); continue; } assert(part.length() > 0); wstring unformattedText = part.unformat(); unsigned partWidth = textWidth(unformattedText, fontName, fontHeight, part.flagsAt(0)); bmp.resize(max(bmp.width(), x + partWidth), bmp.height()); drawText(bmp, unformattedText, x, i * fontHeight, part.colorAt(0), fontName, fontHeight, part.flagsAt(0)); x += partWidth; } } return bmp; }
void Gosu::loadImageFile(Gosu::Bitmap& bitmap, Reader input) { stbi_io_callbacks callbacks; callbacks.read = readCallback; callbacks.skip = skipCallback; callbacks.eof = eofCallback; int x, y, n; stbi_uc* bytes = stbi_load_from_callbacks(&callbacks, &input, &x, &y, &n, STBI_rgb_alpha); if (bytes == 0) { // TODO - stbi_failure_reason is not thread safe. Everything here should be wrapped in a mutex. throw std::runtime_error("Cannot load image: " + std::string(stbi_failure_reason())); } bitmap.resize(x, y); std::memcpy(bitmap.data(), bytes, x * y * sizeof(Gosu::Color)); stbi_image_free(bytes); }
void Gosu::saveImageFile(const Gosu::Bitmap& bitmap, const std::wstring& filename) { int ok; std::string utf8 = Gosu::wstringToUTF8(filename); if (isExtension(filename.c_str(), L"bmp")) { ok = stbi_write_bmp(utf8.c_str(), bitmap.width(), bitmap.height(), 4, bitmap.data()); } else if (isExtension(filename.c_str(), L"tga")) { ok = stbi_write_tga(utf8.c_str(), bitmap.width(), bitmap.height(), 4, bitmap.data()); } else { ok = stbi_write_png(utf8.c_str(), bitmap.width(), bitmap.height(), 4, bitmap.data(), 0); } if (ok == 0) throw std::runtime_error("Could not save image data to file: " + utf8); }
Gosu::Bitmap Gosu::Texture::toBitmap(unsigned x, unsigned y, unsigned width, unsigned height) const { #ifdef GOSU_IS_IPHONE throw std::logic_error("Texture::toBitmap not supported on iOS"); #else Gosu::Bitmap fullTexture; fullTexture.resize(size(), size()); glBindTexture(GL_TEXTURE_2D, name); glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, fullTexture.data()); Gosu::Bitmap bitmap; bitmap.resize(width, height); bitmap.insert(fullTexture, -int(x), -int(y)); return bitmap; #endif }