Extract images from a PDF or ZIP file
"Egyptian" brackets is uncommon practice for C#. You should place an opening brace on separate line.



I suggest to use Dictionary every time you deal with mapping:

private const string ZipExtension = "zip";
private const string PdfExtension = "pdf";

private static readonly Dictionary&lt;string, Func&lt;IPack&gt;&gt; PackCreators =
    new Dictionary&lt;string, Func&lt;IPack&gt;&gt;(StringComparer.OrdinalIgnoreCase)
    {
        [ZipExtension] = () =&gt; new ZipPack(),
        [PdfExtension] = () =&gt; new PdfPack()
    };


Then you can obtain an instance of pack with this code:

if (!PackCreators.TryGetValue(extension, out var packCreator))
    throw new InvalidOperationException("Invalid file type.");

var pack = packCreator();




Once you've got a pack instance you can perform all actions with it inside using block:

using (pack)
{
    pack.Open(inputStream);
    // ...
}


which eliminates the need to define pack outside of try-finally and the need of try-finally itself with explicit pack disposing.



You calculate i % numPages multiple times in your loop. Define a variable and use it:

var remainder = i % numPages;

if (remainder == 0)
// ...
$"{groupId}/{remainder }"
// ...
if (remainder == numPages - 1)