DPI(dots per inch) PPI(pixel per inch) 求一张图片在某分辨率下的实际尺寸?求计算机显示器PPI? MFC按600dpi时的实际物理尺寸打印图片

2023-05-16

标准固定

1 寸=3.3333333 厘米
1 英寸=2.54 厘米

求计算机显示器PPI?

比如对角线14英寸,不是寸,即2.54*14=35.56cm
按16:9算出宽和高 高(9x)2+宽(16x)2=对角线35.56cm2   算出宽*高:30.99*17.43cm  即30.99/2.54英寸
像素为1920*1080  PPI=1920*2.54/30.99= 约157PPI(pixel per inch)

求一张图片在某分辨率下的实际尺寸?

比如600PPI(pixel per inch 显示器)或DPI(dots per inch 打印机) ,像素为1920*1080,算宽*高各为多少英寸或厘米?

像素为1920*1080,打印机为600dpi
宽=1920/600 英寸=1920/600*2.54 厘米=8.128 厘米
高=1080/600 英寸=1080/600*2.54 厘米=4.572 厘米

现在改为打印机300dpi,要求实际物理尺寸不变。
宽=width/300 英寸=width/300*2.54 厘米=8.128 厘米
高=height/300 英寸=height/300*2.54 厘米=4.572 厘米
必须缩放图片像素为960*540

所以,不同点数的打印机要按实际物理尺寸打印图片,那必须缩放图片,即改变像素。实际尺寸以打印机为600dpi为标准:currnet_x_pix=old_x_pix/600*currnet_dpi

C#按物理尺寸打印图片 e.Graphics.DrawImage(image,0,0); //按物理尺寸打印标签,600点改为300点的打印机_小黄人软件的博客-CSDN博客

MFC按实际物理尺寸打印图片

方法1.获得打印机点数,按点数转换图片像素


#include "pch.h"
#include "../pch.h"
#include "../utility/utility.h"
#include <atlbase.h> 


using namespace Gdiplus;
int GetEncoderClsid(const WCHAR* format, CLSID* pClsid)
{
	UINT  num = 0;          // number of image encoders
	UINT  size = 0;         // size of the image encoder array in bytes

	ImageCodecInfo* pImageCodecInfo = NULL;

	GetImageEncodersSize(&num, &size);
	if (size == 0)
		return -1;  // Failure

	pImageCodecInfo = (ImageCodecInfo*)(malloc(size));
	if (pImageCodecInfo == NULL)
		return -1;  // Failure

	GetImageEncoders(num, size, pImageCodecInfo);

	for (UINT j = 0; j < num; ++j)
	{
		if (wcscmp(pImageCodecInfo[j].MimeType, format) == 0)
		{
			*pClsid = pImageCodecInfo[j].Clsid;
			free(pImageCodecInfo);
			return j;  // Success
		}
	}

	free(pImageCodecInfo);
	return -1;  // Failure
}
BOOL getBMPInfo(LPCTSTR  fileName)
{
	// Initialize GDI+.
	GdiplusStartupInput gdiplusStartupInput;
	ULONG_PTR gdiplusToken;
	GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);


	USES_CONVERSION;
	Gdiplus::Bitmap* pBitmap = new Gdiplus::Bitmap(T2W(fileName));
	if (pBitmap == NULL || pBitmap->GetLastStatus() != Gdiplus::Ok) { logger.ERROR_F(__FUNCTION__+to_string(__LINE__)+"出错:" + to_string(pBitmap->GetLastStatus()));  delete pBitmap;	return FALSE; }

	logger.INFO_F("水平*垂直分辨率:" +to_string(pBitmap->GetHorizontalResolution()) + "*" + to_string(pBitmap->GetVerticalResolution()));
	logger.INFO_F("width*height像素:" + to_string(pBitmap->GetWidth())+"*"+ to_string(pBitmap->GetHeight()));
	logger.INFO_F("600dpi时width*height厘米:" + to_string((float)(pBitmap->GetWidth())*2.54 /600) + "*" + to_string((float)(pBitmap->GetHeight())*2.54 /600));
	//if (abs(pBitmap->GetHorizontalResolution() - dpi)>0.5 || abs(pBitmap->GetVerticalResolution() - dpi)> 0.5)
	//{
	//	logger.ERROR_F("水平分辨率" + to_string(pBitmap->GetHorizontalResolution()) + "或垂直分辨率" + to_string(pBitmap->GetVerticalResolution()) + " 错误,应该为" + to_string(dpi));
	//	delete pBitmap;
	//	return FALSE;
	//}
	delete pBitmap;
	return TRUE;
}
BOOL setBMPResolution(LPCTSTR  fileName, float dpi)
{
	LPCTSTR outFileName = "temp.bmp";
	// Initialize GDI+.
	GdiplusStartupInput gdiplusStartupInput;
	ULONG_PTR gdiplusToken;
	GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);


	USES_CONVERSION;
	Gdiplus::Bitmap* pBitmap = new Gdiplus::Bitmap(T2W(fileName));
	if (pBitmap==NULL || pBitmap->GetLastStatus() != Gdiplus::Ok) { logger.ERROR_F("转分辨率出错:" + to_string(pBitmap->GetLastStatus()));  delete pBitmap;	return FALSE; }

	Gdiplus::Status status = pBitmap->SetResolution(dpi, dpi);//设置此 Bitmap 的分辨率。
	if (status != Gdiplus::Ok) { logger.ERROR_F("转分辨率:" + to_string(status));  delete pBitmap;	return FALSE; }
	
	
	CLSID clsid;
	GetEncoderClsid(L"image/bmp", &clsid);				//Get the encoder
	status = pBitmap->Save(T2W(outFileName), &clsid);//Save the image into physical memory
	if (status != Gdiplus::Ok) { logger.ERROR_F("转分辨率后,保存错误:" + to_string(status)); delete pBitmap;	return FALSE; }
	delete pBitmap;
	
	pipe_system("del "+ (CString)fileName+"\n", DELAY); //cmd先删除
	pipe_system("rename " + (CString)outFileName + " "+ fileName +"\n", DELAY); //cmd重命名为原来的名
	logger.INFO_F(string(fileName)+"设置分辨率成功:" + to_string(dpi));
	return TRUE;
}

void PrintBitmap(LPCTSTR filename)
{
	//setBMPResolution(filename, 600);//转为600分辨率
	getBMPInfo(filename);

	CPrintDialog printDlg(FALSE);
	printDlg.GetDefaults(); 

	CDC dc;
	if (!dc.Attach(printDlg.GetPrinterDC())) {
		AfxMessageBox(_T("No printer found!")); return;
	} 

	dc.m_bPrinting = TRUE; 
	DOCINFO di;    
	// Initialise print document details
	::ZeroMemory (&di, sizeof (DOCINFO));
	di.cbSize = sizeof (DOCINFO);
	di.lpszDocName = filename; //显示在打印列表里的名字
	BOOL bPrintingOK = dc.StartDoc(&di); // Begin a new print job 
	// Get the printing extents
	// and store in the m_rectDraw field of a 
	// CPrintInfo object
	CPrintInfo Info;
	Info.SetMaxPage(1); // just one page 

	
	//打印机页面的水平和垂直像素
	int maxw = dc.GetDeviceCaps(HORZRES);
	int maxh = dc.GetDeviceCaps(VERTRES); 
	//打印机每英寸像素数
	int cxInch = dc.GetDeviceCaps(LOGPIXELSX);
	int cyInch = dc.GetDeviceCaps(LOGPIXELSY);
	logger.INFO_F("页面:" + to_string(maxw)+"*"+to_string(maxh) + " 打印机DPI:" + to_string(cxInch)+"*"+to_string(cyInch)); //mm 纸尺寸  
	Info.m_rectDraw.SetRect(0, 0, maxw, maxh);
	for (UINT page = Info.GetMinPage(); page <= 
		Info.GetMaxPage() && bPrintingOK; page++) {
			dc.StartPage();    // begin new page
			Info.m_nCurPage = page;
			CBitmap bitmap;
			// LoadImage does the trick here, it creates a DIB section
			// You can also use a resource here
			// by using MAKEINTRESOURCE() ... etc. 
			if(!bitmap.Attach(::LoadImage(
				::GetModuleHandle(NULL), filename, IMAGE_BITMAP, 0, 0, 
				LR_LOADFROMFILE | LR_CREATEDIBSECTION | LR_DEFAULTSIZE))) {
					AfxMessageBox(_T("Error loading bitmap!")); return;
			} 
			BITMAP bm;
			bitmap.GetBitmap(&bm);//获得宽与高

			// create memory device context
			CDC memDC; 
			memDC.CreateCompatibleDC(&dc);
			CBitmap *pBmp = memDC.SelectObject(&bitmap);
			memDC.SetMapMode(dc.GetMapMode());

			dc.StretchBlt(0, 0, bm.bmWidth * cxInch / 600 , bm.bmHeight * cyInch / 600 , &memDC, 0, 0, bm.bmWidth, bm.bmHeight, SRCCOPY);//按600dpi时的实际尺寸打印
			//dc.BitBlt(0, 0, bm.bmWidth, bm.bmHeight, &memDC, 0, 0, SRCCOPY); //按图片大小打印
			// clean up
			memDC.SelectObject(pBmp);
			bPrintingOK = (dc.EndPage() > 0);   // end page
	} 
	if (bPrintingOK)
		dc.EndDoc(); // end a print job
	else dc.AbortDoc();           // abort job. 
}

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

DPI(dots per inch) PPI(pixel per inch) 求一张图片在某分辨率下的实际尺寸?求计算机显示器PPI? MFC按600dpi时的实际物理尺寸打印图片 的相关文章

随机推荐