/// <summary> /// Save the current render results to a file. /// This could benefit from QImageWriter, however its compression capabilities are /// severely lacking. A Png file comes out larger than a bitmap, so instead use the /// Png and Jpg wrapper functions from the command line programs. /// This will embed the id, url and nick fields from the options in the image comments. /// </summary> /// <param name="filename">The full path and filename</param> /// <param name="comments">The comments to save in the png or jpg</param> /// <param name="pixels">The buffer containing the pixels</param> /// <param name="width">The width in pixels of the image</param> /// <param name="height">The height in pixels of the image</param> /// <param name="channels">The number of channels, 3 or 4.</param> /// <param name="bpc">The bytes per channel, almost always 1.</param> void FractoriumEmberControllerBase::SaveCurrentRender(const QString& filename, const EmberImageComments& comments, vector<byte>& pixels, size_t width, size_t height, size_t channels, size_t bpc) { if (filename != "") { bool b = false; uint i, j; byte* data = nullptr; vector<byte> vecRgb; QFileInfo fileInfo(filename); QString suffix = fileInfo.suffix(); FractoriumSettings* settings = m_Fractorium->m_Settings; //Ensure dimensions are valid. if (pixels.size() < (width * height * channels * bpc)) { m_Fractorium->ShowCritical("Save Failed", "Dimensions didn't match, not saving.", true); return; } data = pixels.data();//Png and channels == 4. if ((suffix == "jpg" || suffix == "bmp") && channels) { RgbaToRgb(pixels, vecRgb, width, height); data = vecRgb.data(); } string s = filename.toStdString(); string id = settings->Id().toStdString(); string url = settings->Url().toStdString(); string nick = settings->Nick().toStdString(); if (suffix == "png") b = WritePng(s.c_str(), data, width, height, 1, true, comments, id, url, nick); else if (suffix == "jpg") b = WriteJpeg(s.c_str(), data, width, height, 100, true, comments, id, url, nick); else if (suffix == "bmp") b = WriteBmp(s.c_str(), data, width, height); else { m_Fractorium->ShowCritical("Save Failed", "Unrecognized format " + suffix + ", not saving.", true); return; } if (b) settings->SaveFolder(fileInfo.canonicalPath()); else m_Fractorium->ShowCritical("Save Failed", "Could not save file, try saving to a different folder.", true); } }
void main() { int fmode=0; int i,j; int red[256]; int green[256]; int blue[256]; FILE *f; char *filename="text_gray.bmp"; ReadBmp(filename,&tmp1); printf("%d %d\n",tmp1.height,tmp1.width); while(1){ printf(" 0:モード法\n 1:判別分析法\n 2:移動平均法\n 3:終了\n"); scanf("%d",&fmode); if(fmode > 2) break; tmp2=tmp1; /* 元の画像ファイルのすべての画像データをコピーする */ reset( red, green, blue ); Gray( &tmp2 , &tmp1 ); set( red , green , blue ); switch(fmode){ case 0 : mode(red); //モード法 break; case 1 : sweep(red); //判別分析法 break; case 2 : mov_ave(red); //移動平均法 break; } WriteBmp("border.bmp",&tmp2); PrintBmpInfo("border.bmp"); } }
void Renderer::RenderEuler3D( float* d, int N, int frame, const char* filename, int width, int height ) { // Eye Position const float eyePos[3] = { 0.5, 0.5, -1.0 }; // Light Position const float lightPos[3] = { 0.5, 1.5, 0.2 }; // Light Intensity const float lightIntensity = 8.0; // Absortion const float absorption = 11.0; // Ray Samples const int numSamples = 128; // Ray Light Samples const int numLightSample = 64; // Maximum Distance const float maxDist = 3.0; // Ray Sampling Space const float stride = maxDist/numSamples; // Light Ray Sampling Space const float lstride = maxDist/numLightSample; // Memory Allocation static unsigned char *image = new unsigned char[width*height*4]; for( int ci=0; ci<width*height; ci++ ) { int i=ci%width; int j=ci/width; // Transmittance float T = 1.0; // In-scattered Radiance float Lo = 0.0; // Pixel Position float pixPos[3] = {i/(float)width,j/(float)height}; // Eye Vector float eyeVec[3] = {pixPos[0]-eyePos[0],pixPos[1]-eyePos[1],pixPos[2]-eyePos[2]}; normalize(eyeVec); // Sphere Hit bool hitSphere = false; float dotProduct = 0.0; // Sample Density... for( int n=0; n<numSamples; n++ ) { // Sample Point float pos[3] = { eyePos[0]+stride*n*eyeVec[0], eyePos[1]+stride*n*eyeVec[1], eyePos[2]+stride*n*eyeVec[2] }; // Sample Density float density = sample3D(d, N, pos); // Skip Empty Density if( density > 0.0 ) { // Attenuate T *= 1.0-density*stride*absorption; if( T <= 0.01 ) break; // Compute Light Ray float lightVec[3] = {lightPos[0]-pos[0],lightPos[1]-pos[1],lightPos[2]-pos[2]}; normalize(lightVec); // Transmittance Along Light Ray float Tl = 1.0; // Sample Density Again... for( int m=1; m<numLightSample; m++ ) { // Sample Point float lpos[3] = { pos[0]+lstride*m*lightVec[0], pos[1]+lstride*m*lightVec[1], pos[2]+lstride*m*lightVec[2] }; // Sample Density float ldensity = sample3D(d, N, lpos); // Attenuate Tl *= 1.0-absorption*lstride*ldensity; if( Tl <= 0.01 ) break; } float Li = lightIntensity*Tl; Lo += Li*T*density*stride; } } // At Floor float Tf = 0.0; if( eyeVec[1] < 0.0 && hitSphere == false ) { float flen = -pixPos[1]/eyeVec[1]; Tf = exp(-0.3*flen); // Compute Floor Intersection float pos[3] = {pixPos[0]+flen*eyeVec[0],pixPos[1]+flen*eyeVec[1],pixPos[2]+flen*eyeVec[2]}; // Compute Light Ray float lightVec[3] = {lightPos[0]-pos[0],lightPos[1]-pos[1],lightPos[2]-pos[2]}; normalize(lightVec); // Sample Density for( int m=1; m<numLightSample; m++ ) { // Sample Point float lpos[3] = { pos[0]+lstride*m*lightVec[0], pos[1]+lstride*m*lightVec[1], pos[2]+lstride*m*lightVec[2] }; // Sample Density float ldensity = sample3D(d, N, lpos); // Attenuate Tf *= 1.0-0.5*absorption*lstride*ldensity; if( Tf <= 0.01 ) break; } } // Floor Color unsigned char floor_color[3] = { 75, 60, 45 }; // Sphere Color unsigned char sphere_color[3] = { 50, 100, 150 }; for( int k=0; k<3; k++ ) { image[4*(i+j*width)+k] = max(0,min(255,255*Lo + T*(Tf*floor_color[k] + dotProduct*sphere_color[k]))); } } char fn[128]; sprintf(fn, "%s_%d.bmp", filename, frame ); WriteBmp(fn, image, width, height, false ); }
bool EmberRender(EmberOptions& opt) { #ifdef USECL EmberCLns::OpenCLInfo& info(EmberCLns::OpenCLInfo::Instance());#endif std::cout.imbue(std::locale("")); if (opt.DumpArgs()) cout << opt.GetValues(OPT_USE_RENDER) << endl; if (opt.OpenCLInfo()) { cout << "\nOpenCL Info: " << endl; cout << info.DumpInfo(); return true; } Timing t; bool writeSuccess = false; byte* finalImagep; uint padding; size_t i, channels; size_t strips; size_t iterCount; string filename; string inputPath = GetPath(opt.Input()); ostringstream os; pair<size_t, size_t> p; vector<Ember<T>> embers; vector<byte> finalImage; EmberStats stats; EmberReport emberReport; EmberImageComments comments; XmlToEmber<T> parser; EmberToXml<T> emberToXml; vector<QTIsaac<ISAAC_SIZE, ISAAC_INT>> randVec; const vector<pair<size_t, size_t>> devices = Devices(opt.Devices()); unique_ptr<RenderProgress<T>> progress(new RenderProgress<T>()); unique_ptr<Renderer<T, float>> renderer(CreateRenderer<T>(opt.EmberCL() ? OPENCL_RENDERER : CPU_RENDERER, devices, false, 0, emberReport)); vector<string> errorReport = emberReport.ErrorReport(); if (!errorReport.empty()) emberReport.DumpErrorReport(); if (!renderer.get()) { cout << "Renderer creation failed, exiting." << endl; return false; } if (opt.EmberCL() && renderer->RendererType() != OPENCL_RENDERER)//OpenCL init failed, so fall back to CPU. opt.EmberCL(false); if (!InitPaletteList<T>(opt.PalettePath())) return false; if (!ParseEmberFile(parser, opt.Input(), embers)) return false; if (!opt.EmberCL()) { if (opt.ThreadCount() == 0) { cout << "Using " << Timing::ProcessorCount() << " automatically detected threads." << endl; opt.ThreadCount(Timing::ProcessorCount()); } else { cout << "Using " << opt.ThreadCount() << " manually specified threads." << endl; } renderer->ThreadCount(opt.ThreadCount(), opt.IsaacSeed() != "" ? opt.IsaacSeed().c_str() : nullptr); } else { cout << "Using OpenCL to render." << endl; if (opt.Verbose()) { for (auto& device : devices) { cout << "Platform: " << info.PlatformName(device.first) << endl; cout << "Device: " << info.DeviceName(device.first, device.second) << endl; } } if (opt.ThreadCount() > 1) cout << "Cannot specify threads with OpenCL, using 1 thread." << endl; opt.ThreadCount(1); renderer->ThreadCount(opt.ThreadCount(), opt.IsaacSeed() != "" ? opt.IsaacSeed().c_str() : nullptr); if (opt.BitsPerChannel() != 8) { cout << "Bits per channel cannot be anything other than 8 with OpenCL, setting to 8." << endl; opt.BitsPerChannel(8); } } if (opt.Format() != "jpg" && opt.Format() != "png" && opt.Format() != "ppm" && opt.Format() != "bmp") { cout << "Format must be jpg, png, ppm, or bmp not " << opt.Format() << ". Setting to jpg." << endl; } channels = opt.Format() == "png" ? 4 : 3; if (opt.BitsPerChannel() == 16 && opt.Format() != "png") { cout << "Support for 16 bits per channel images is only present for the png format. Setting to 8." << endl; opt.BitsPerChannel(8); } else if (opt.BitsPerChannel() != 8 && opt.BitsPerChannel() != 16) { cout << "Unexpected bits per channel specified " << opt.BitsPerChannel() << ". Setting to 8." << endl; opt.BitsPerChannel(8); } if (opt.InsertPalette() && opt.BitsPerChannel() != 8) { cout << "Inserting palette only supported with 8 bits per channel, insertion will not take place." << endl; opt.InsertPalette(false); } if (opt.AspectRatio() < 0) { cout << "Invalid pixel aspect ratio " << opt.AspectRatio() << endl << ". Must be positive, setting to 1." << endl; opt.AspectRatio(1); } if (!opt.Out().empty() && (embers.size() > 1)) { cout << "Single output file " << opt.Out() << " specified for multiple images. Changing to use prefix of badname-changethis instead. Always specify prefixes when reading a file with multiple embers." << endl; opt.Out(""); opt.Prefix("badname-changethis"); } //Final setup steps before running. os.imbue(std::locale("")); padding = uint(std::log10(double(embers.size()))) + 1; renderer->EarlyClip(opt.EarlyClip()); renderer->YAxisUp(opt.YAxisUp()); renderer->LockAccum(opt.LockAccum()); renderer->InsertPalette(opt.InsertPalette()); renderer->PixelAspectRatio(T(opt.AspectRatio())); renderer->Transparency(opt.Transparency()); renderer->NumChannels(channels); renderer->BytesPerChannel(opt.BitsPerChannel() / 8); renderer->Priority(eThreadPriority(Clamp<intmax_t>(intmax_t(opt.Priority()), intmax_t(eThreadPriority::LOWEST), intmax_t(eThreadPriority::HIGHEST)))); renderer->Callback(opt.DoProgress() ? progress.get() : nullptr); for (i = 0; i < embers.size(); i++) { if (opt.Verbose() && embers.size() > 1) cout << "\nFlame = " << i + 1 << "/" << embers.size() << endl; else if (embers.size() > 1) VerbosePrint(endl); if (opt.Supersample() > 0) embers[i].m_Supersample = opt.Supersample(); if (opt.SubBatchSize() != DEFAULT_SBS) embers[i].m_SubBatchSize = opt.SubBatchSize(); embers[i].m_TemporalSamples = 1;//Force temporal samples to 1 for render. embers[i].m_Quality *= T(opt.QualityScale()); embers[i].m_FinalRasW = size_t(T(embers[i].m_FinalRasW) * opt.SizeScale()); embers[i].m_FinalRasH = size_t(T(embers[i].m_FinalRasH) * opt.SizeScale()); embers[i].m_PixelsPerUnit *= T(opt.SizeScale()); if (embers[i].m_FinalRasW == 0 || embers[i].m_FinalRasH == 0) { cout << "Output image " << i << " has dimension 0: " << embers[i].m_FinalRasW << ", " << embers[i].m_FinalRasH << ". Setting to 1920 x 1080." << endl; embers[i].m_FinalRasW = 1920; embers[i].m_FinalRasH = 1080; } //Cast to double in case the value exceeds 2^32. double imageMem = double(renderer->NumChannels()) * double(embers[i].m_FinalRasW) * double(embers[i].m_FinalRasH) * double(renderer->BytesPerChannel()); double maxMem = pow(2.0, double((sizeof(void*) * 8) - 1)); if (imageMem > maxMem)//Ensure the max amount of memory for a process is not exceeded. { cout << "Image " << i << " size > " << maxMem << ". Setting to 1920 x 1080." << endl; embers[i].m_FinalRasW = 1920; embers[i].m_FinalRasH = 1080; } stats.Clear(); renderer->SetEmber(embers[i]); renderer->PrepFinalAccumVector(finalImage);//Must manually call this first because it could be erroneously made smaller due to strips if called inside Renderer::Run(). if (opt.Strips() > 1) { strips = opt.Strips(); } else { p = renderer->MemoryRequired(1, true, false);//No threaded write for render, only for animate. strips = CalcStrips(double(p.second), double(renderer->MemoryAvailable()), opt.UseMem()); if (strips > 1) VerbosePrint("Setting strips to " << strips << " with specified memory usage of " << opt.UseMem()); } strips = VerifyStrips(embers[i].m_FinalRasH, strips, [&](const string& s) { cout << s << endl; },//Greater than height. [&](const string& s) { cout << s << endl; },//Mod height != 0. [&](const string& s) { cout << s << endl; });//Final strips value to be set. //For testing incremental renderer. //int sb = 1; //bool resume = false, success = false; //do //{ // success = renderer->Run(finalImage, 0, sb, false/*resume == false*/) == RENDER_OK; // sb++; // resume = true; //} //while (success && renderer->ProcessState() != ACCUM_DONE); StripsRender<T>(renderer.get(), embers[i], finalImage, 0, strips, opt.YAxisUp(), [&](size_t strip)//Pre strip. { if (opt.Verbose() && (strips > 1) && strip > 0) cout << endl; if (strips > 1) VerbosePrint("Strip = " << (strip + 1) << "/" << strips); }, [&](size_t strip)//Post strip. { progress->Clear(); stats += renderer->Stats(); }, [&](size_t strip)//Error. { cout << "Error: image rendering failed, skipping to next image." << endl; renderer->DumpErrorReport();//Something went wrong, print errors. }, //Final strip. //Original wrote every strip as a full image which could be very slow with many large images. //Only write once all strips for this image are finished. [&](Ember<T>& finalEmber) { if (!opt.Out().empty()) { filename = opt.Out(); } else if (opt.NameEnable() && !finalEmber.m_Name.empty()) { filename = inputPath + opt.Prefix() + finalEmber.m_Name + opt.Suffix() + "." + opt.Format(); } else { ostringstream fnstream; fnstream << inputPath << opt.Prefix() << setfill('0') << setw(padding) << i << opt.Suffix() << "." << opt.Format(); filename = fnstream.str(); } //TotalIterCount() is actually using ScaledQuality() which does not get reset upon ember assignment, //so it ends up using the correct value for quality * strips. iterCount = renderer->TotalIterCount(1); comments = renderer->ImageComments(stats, opt.PrintEditDepth(), opt.IntPalette(), opt.HexPalette()); os.str(""); os << comments.m_NumIters << " / " << iterCount << " (" << std::fixed << std::setprecision(2) << ((double(stats.m_Iters) / double(iterCount)) * 100) << "%)"; VerbosePrint("\nIters ran/requested: " + os.str()); if (!opt.EmberCL()) VerbosePrint("Bad values: " << stats.m_Badvals); VerbosePrint("Render time: " + t.Format(stats.m_RenderMs)); VerbosePrint("Pure iter time: " + t.Format(stats.m_IterMs)); VerbosePrint("Iters/sec: " << size_t(stats.m_Iters / (stats.m_IterMs / 1000.0)) << endl); VerbosePrint("Writing " + filename); if ((opt.Format() == "jpg" || opt.Format() == "bmp") && renderer->NumChannels() == 4) RgbaToRgb(finalImage, finalImage, renderer->FinalRasW(), renderer->FinalRasH()); finalImagep = finalImage.data(); writeSuccess = false; if (opt.Format() == "png") writeSuccess = WritePng(filename.c_str(), finalImagep, finalEmber.m_FinalRasW, finalEmber.m_FinalRasH, opt.BitsPerChannel() / 8, opt.PngComments(), comments, opt.Id(), opt.Url(), opt.Nick()); else if (opt.Format() == "jpg") writeSuccess = WriteJpeg(filename.c_str(), finalImagep, finalEmber.m_FinalRasW, finalEmber.m_FinalRasH, int(opt.JpegQuality()), opt.JpegComments(), comments, opt.Id(), opt.Url(), opt.Nick()); else if (opt.Format() == "ppm") writeSuccess = WritePpm(filename.c_str(), finalImagep, finalEmber.m_FinalRasW, finalEmber.m_FinalRasH); else if (opt.Format() == "bmp") writeSuccess = WriteBmp(filename.c_str(), finalImagep, finalEmber.m_FinalRasW, finalEmber.m_FinalRasH); if (!writeSuccess) cout << "Error writing " << filename << endl; }); if (opt.EmberCL() && opt.DumpKernel()) { if (auto rendererCL = dynamic_cast<RendererCL<T, float>*>(renderer.get())) { cout << "Iteration kernel:\n" << rendererCL->IterKernel() << "\n\n" << "Density filter kernel:\n" << rendererCL->DEKernel() << "\n\n" << "Final accumulation kernel:\n" << rendererCL->FinalAccumKernel() << endl; } } VerbosePrint("Done."); } t.Toc("\nFinished in: ", true); return true; }
bool Encryption(char *file_in_name){ //初期化 char *file_out_name;//画像の出力・入力ファイル名 char *key_out_file;//鍵ファイル char *buf; img *imagein, *imageout; int h, w; int i = 0; int registered_num = 0;//色の登録数 angou *code;//色を変換するテーブル FILE* fp; srand((unsigned)time(NULL)); file_out_name = (char *)malloc(sizeof(char)*(strlen(file_in_name) + 10)); strcpy(file_out_name, file_in_name); strcat(file_out_name, "_conv.bmp"); key_out_file = (char *)malloc(sizeof(char)*(strlen(file_in_name) + 8)); buf = (char *)malloc(sizeof(char)*(strlen(file_in_name) + 1)); strcpy(buf, file_in_name); strcpy(key_out_file, buf); strcat(key_out_file, "_key.kp"); imagein = (img *)malloc(sizeof(img)); imageout = (img *)malloc(sizeof(img)); ReadBmp(file_in_name, imagein); code = (angou *)malloc(sizeof(angou)*imagein->height*imagein->width); imageout = imagein; if ((fp = fopen(key_out_file, "w")) == NULL){ MessageBox(NULL, TEXT("key file output error."), NULL, MB_OK); return false; } //画像処理 for (h = 0; h < imagein->height; h++){ for (w = 0; w < imagein->width; w++){ for (i = 0; i <= registered_num; i++){ if (memcmp(&code[i].original_color, &imagein->data[h][w], sizeof(code[i].original_color)) == 0){ //登録してある色が見つかったら代入 imageout->data[h][w] = code[i].converted_color; goto searched_out; } } //変換する色の登録 //変換前の色を登録 code[registered_num].original_color = imagein->data[h][w]; try_again: //変換後の色を登録 code[registered_num].converted_color.r = rand() % 256; code[registered_num].converted_color.g = rand() % 256; code[registered_num].converted_color.b = rand() % 256; ///*変換後の色が既に登録してある色だったら // 変換後の色の登録をやり直す*/ for (i = 0; i < registered_num; i++){ if (memcmp(&code[registered_num].converted_color, &code[i].converted_color, sizeof(code[registered_num].converted_color)) == 0){ goto try_again; } } //出力画像に変換後の色を代入 imageout->data[h][w] = code[registered_num].converted_color; registered_num++; searched_out: ; } } fwrite(code, sizeof(angou), registered_num, fp);//鍵ファイルに変換情報を記録 WriteBmp(file_out_name, imageout); //後処理 fclose(fp); //free(file_out_name); /*free(key_out_file);*/ free(buf); free(code); return true; }