[新手上路]批处理新手入门导读[视频教程]批处理基础视频教程[视频教程]VBS基础视频教程[批处理精品]批处理版照片整理器
[批处理精品]纯批处理备份&还原驱动[批处理精品]CMD命令50条不能说的秘密[在线下载]第三方命令行工具[在线帮助]VBScript / JScript 在线参考
返回列表 发帖

[问题求助] PowerShell怎样将截图png质量改成256色

找了如下一段代码, 可以将屏幕截图, 可设质量, 但我想保存为256色的png图片, 如何设置? 请求路过高手指引, 提前感谢!
  1. function scr {
  2.         param (
  3.                 [string]$location,
  4.                 [int]$quality,
  5.                 [switch]$allscreen
  6.         )
  7.         Add-Type -AssemblyName system.windows.Forms
  8.         if ($allscreen.IsPresent)
  9.         {
  10.                 $Capture = [system.windows.Forms.screen]::Allscreens
  11.         }
  12.         else
  13.         {
  14.                 $Capture = [system.windows.Forms.Screen]::Primaryscreen
  15.         }
  16.         if ($Allscreens)
  17.         {
  18.                 $Capture = [system.windows.Forms.screen]::Allscreens
  19.         }
  20.         else
  21.         {
  22.                 $Capture = [system.windows.Forms.Screen]::PrimaryScreen
  23.         }
  24.         foreach ($C in $Capture)
  25.         {
  26.                 $filename = $location + (get-date).ToString("yyy-M-dd-H-ss") + ".png"
  27.                 $Bitmap = New-object System.Drawing.Bitmap($C.Bounds.width, $C.Bounds.Height)
  28.                 $G = [System.Drawing.Graphics]::FromImage($Bitmap)
  29.                 $G.CopyFromscreen($C.Bounds.Location, (New-object system.Drawing.Point(0, 0)), $C.Bounds.Size)
  30.                 $G.Dispose()
  31.                 $Encoderparam = [system.Drawing.Imaging.Encoder]::Quality
  32.                 $Encoderparamset = New-object System.Drawing.Imaging.EnCoderparameters(1)
  33.                 $Encoderparamset.Param[0] = New-object system.Drawing.Imaging.Encoderparameter($Encoderparam, $Quality)
  34.                 $JPGCodec = [system.Drawing.Imaging.ImageCodecInfo]::GetImageEncoders() | where{
  35.                         $_.MimeType -eq 'image/png' #可设 jpeg  gif png                }
  36.                 $Bitmap.Save($FileName, $JPGCodec, $Encoderparamset)
  37.         }
  38.         
  39. }
  40. scr -location "C:\Users\Administrator\Desktop\" -quality 80 -allscreen
复制代码
本人所发所有贴子或代码, 诸大侠若认为有改进之处,请不吝赐教,感激不尽!

另存为gif 颜色数就256了, 但是有好多噪点, 我从png手动另存为gif就没有噪点, 期待高手指引一下
本人所发所有贴子或代码, 诸大侠若认为有改进之处,请不吝赐教,感激不尽!

TOP

国外找了段代码, 但是一直报错
  1. # PowerShell gif encoding + wrapper around https://www.developerfusion.com/code/4630/capture-a-screen-shot/
  2. Add-Type -TypeDefinition @'
  3. using System;
  4. using System.Runtime.InteropServices;
  5. using System.Drawing;
  6. using System.Drawing.Imaging;
  7. namespace GDI
  8. {
  9.     /// <summary>
  10.     /// Provides functions to capture the entire screen, or a particular window, and save it to a file.
  11.     /// </summary>
  12.     public class ScreenCapture
  13.     {
  14.         /// <summary>
  15.         /// Creates an Image object containing a screen shot of the entire desktop
  16.         /// </summary>
  17.         /// <returns></returns>
  18.         public Image CaptureScreen()
  19.         {
  20.             return CaptureWindow( User32.GetDesktopWindow() );
  21.         }
  22.         /// <summary>
  23.         /// Creates an Image object containing a screen shot of a specific window
  24.         /// </summary>
  25.         /// <param name="handle">The handle to the window. (In windows forms, this is obtained by the Handle property)</param>
  26.         /// <returns></returns>
  27.         public Image CaptureWindow(IntPtr handle)
  28.         {
  29.             // get te hDC of the target window
  30.             IntPtr hdcSrc = User32.GetWindowDC(handle);
  31.             // get the size
  32.             User32.RECT windowRect = new User32.RECT();
  33.             User32.GetWindowRect(handle,ref windowRect);
  34.             int width = windowRect.right - windowRect.left;
  35.             int height = windowRect.bottom - windowRect.top;
  36.             // create a device context we can copy to
  37.             IntPtr hdcDest = GDI32.CreateCompatibleDC(hdcSrc);
  38.             // create a bitmap we can copy it to,
  39.             // using GetDeviceCaps to get the width/height
  40.             IntPtr hBitmap = GDI32.CreateCompatibleBitmap(hdcSrc,width,height);
  41.             // select the bitmap object
  42.             IntPtr hOld = GDI32.SelectObject(hdcDest,hBitmap);
  43.             // bitblt over
  44.             GDI32.BitBlt(hdcDest,0,0,width,height,hdcSrc,0,0,GDI32.SRCCOPY);
  45.             // restore selection
  46.             GDI32.SelectObject(hdcDest,hOld);
  47.             // clean up
  48.             GDI32.DeleteDC(hdcDest);
  49.             User32.ReleaseDC(handle,hdcSrc);
  50.             // get a .NET image object for it
  51.             Image img = Image.FromHbitmap(hBitmap);
  52.             // free up the Bitmap object
  53.             GDI32.DeleteObject(hBitmap);
  54.             return img;
  55.         }
  56.         /// <summary>
  57.         /// Captures a screen shot of a specific window, and saves it to a file
  58.         /// </summary>
  59.         /// <param name="handle"></param>
  60.         /// <param name="filename"></param>
  61.         /// <param name="format"></param>
  62.         public void CaptureWindowToFile(IntPtr handle, string filename, ImageFormat format)
  63.         {
  64.             Image img = CaptureWindow(handle);
  65.             img.Save(filename,format);
  66.         }
  67.         /// <summary>
  68.         /// Captures a screen shot of the entire desktop, and saves it to a file
  69.         /// </summary>
  70.         /// <param name="filename"></param>
  71.         /// <param name="format"></param>
  72.         public void CaptureScreenToFile(string filename, ImageFormat format)
  73.         {
  74.             Image img = CaptureScreen();
  75.             img.Save(filename,format);
  76.         }
  77.       
  78.         /// <summary>
  79.         /// Helper class containing Gdi32 API functions
  80.         /// </summary>
  81.         private class GDI32
  82.         {
  83.             
  84.             public const int SRCCOPY = 0x00CC0020; // BitBlt dwRop parameter
  85.             [DllImport("gdi32.dll")]
  86.             public static extern bool BitBlt(IntPtr hObject,int nXDest,int nYDest,
  87.                 int nWidth,int nHeight,IntPtr hObjectSource,
  88.                 int nXSrc,int nYSrc,int dwRop);
  89.             [DllImport("gdi32.dll")]
  90.             public static extern IntPtr CreateCompatibleBitmap(IntPtr hDC,int nWidth,
  91.                 int nHeight);
  92.             [DllImport("gdi32.dll")]
  93.             public static extern IntPtr CreateCompatibleDC(IntPtr hDC);
  94.             [DllImport("gdi32.dll")]
  95.             public static extern bool DeleteDC(IntPtr hDC);
  96.             [DllImport("gdi32.dll")]
  97.             public static extern bool DeleteObject(IntPtr hObject);
  98.             [DllImport("gdi32.dll")]
  99.             public static extern IntPtr SelectObject(IntPtr hDC,IntPtr hObject);
  100.         }
  101.         /// <summary>
  102.         /// Helper class containing User32 API functions
  103.         /// </summary>
  104.         private class User32
  105.         {
  106.             [StructLayout(LayoutKind.Sequential)]
  107.             public struct RECT
  108.             {
  109.                 public int left;
  110.                 public int top;
  111.                 public int right;
  112.                 public int bottom;
  113.             }
  114.             [DllImport("user32.dll")]
  115.             public static extern IntPtr GetDesktopWindow();
  116.             [DllImport("user32.dll")]
  117.             public static extern IntPtr GetWindowDC(IntPtr hWnd);
  118.             [DllImport("user32.dll")]
  119.             public static extern IntPtr ReleaseDC(IntPtr hWnd,IntPtr hDC);
  120.             [DllImport("user32.dll")]
  121.             public static extern IntPtr GetWindowRect(IntPtr hWnd,ref RECT rect);
  122.         }
  123.     }
  124. }
  125. '@ -Language CSharp -ReferencedAssemblies system.drawing
  126. function Capture-Screen
  127. {
  128. param (
  129. [GDI.ScreenCapture]$SC
  130. )
  131. $Filename = Join-Path $PWD "capt$(Date -Format yyMMddhhmmssffff).bmp"
  132. $SC.CaptureWindowToFile((Get-Process -Id $PID).MainWindowHandle, $Filename, 'Bmp')
  133. }
  134. # Generate some random output, take screenshots
  135. 0 .. 10 | %{
  136. Get-Random
  137. Capture-Screen -SC $sc
  138. Start-Sleep -Milliseconds 200
  139. }
  140. $enc = [System.Windows.Media.Imaging.GifBitmapEncoder]::new()
  141. foreach ($frame in Get-ChildItem .\capt*.bmp)
  142. {
  143. $bmp = [System.Drawing.Bitmap]::FromFile($frame.FullName)
  144. $hbmp = $bmp.GetHbitMap()
  145. $bmpsrc = [System.Windows.Interop.Imaging]::CreateBitmapSourceFromHBitmap($hbmp, [System.IntPtr]::Zero, 'Empty', [System.Windows.Media.Imaging.BitmapSizeOptions]::FromEmptyOptions())
  146. $enc.Frames.Add([System.Windows.Media.Imaging.BitmapFrame]::Create($bmpsrc))
  147. $hbmp = $bmp = $null
  148. }
  149. $filestream = [System.IO.File]::Create((Join-Path $PWD output.gif))
  150. $enc.Save($filestream)
  151. Remove-Item .\capt*.bmp
复制代码
本人所发所有贴子或代码, 诸大侠若认为有改进之处,请不吝赐教,感激不尽!

TOP

这是不是绕了什么弯路?
虽然不懂Powershell

TOP

回复 4# 523066680

有可能

gg搜索了一下, C#实现 png转8位256色png, 是个"世界难题", 好多解决办法都用别的组件了, 或用很长的代码实现的
存成gif是现成的, 但是会有噪点, 坐等高手指路
本人所发所有贴子或代码, 诸大侠若认为有改进之处,请不吝赐教,感激不尽!

TOP

本帖最后由 5i365 于 2022-5-24 21:32 编辑

gif解决噪点, 找到一个文章, 但是不能下载, 估计很麻烦,
https://www.cnblogs.com/mier/archive/2009/04/26/1443699.html
哎, 感觉自己解决问题, 好吃力, 遇到的问题, 都是难题, 还是我水平太low了
本人所发所有贴子或代码, 诸大侠若认为有改进之处,请不吝赐教,感激不尽!

TOP

一楼的改一下27行试试
  1. $Bitmap = New-object System.Drawing.Bitmap($C.Bounds.width, $C.Bounds.Height,198659)
  2. #https://docs.microsoft.com/zh-cn/dotnet/api/system.drawing.bitmap.-ctor#system-drawing-bitmap-ctor(system-int32-system-int32-system-int32-system-drawing-imaging-pixelformat-system-intptr)
  3. #https://docs.microsoft.com/zh-cn/dotnet/api/system.drawing.imaging.pixelformat
复制代码

TOP

本帖最后由 5i365 于 2022-5-25 07:00 编辑

回复 7# idwma


   感谢大侠指引, 加上后,会报如下错误, 并生成了一个全黑的图片
ERROR: Exception calling "FromImage" with "1" argument(s): "A Graphics object cannot be created from an image that has an indexed pixel format."
我需要的就是将屏幕截为一张
没有噪点的gif图片
或者8位的png图片, 都可以, 因为别的格式图片体积太大了
本人所发所有贴子或代码, 诸大侠若认为有改进之处,请不吝赐教,感激不尽!

TOP

返回列表